将 Javascript 正则表达式转换为 Java 语法

Posted

技术标签:

【中文标题】将 Javascript 正则表达式转换为 Java 语法【英文标题】:Convert Javascript regular expression to Java syntax 【发布时间】:2012-02-03 23:34:32 【问题描述】:

我知道 regEx 在各种语言中都很常见...但是我在编写 Java 语法时遇到了麻烦。 我有一个用 JS 编码的正则表达式;

if((/[a-zA-Z]/).test(str) && (/[0-9]|[\x21-\x2F|\x3A-\x40|\x5B-\x60|\x7B-\x7E]/).test(str))         
return true;

如何在 Java 中编写相同的内容?

我已经导入

import java.util.regex.Matcher;
import java.util.regex.Pattern;

补充一下,从我的尝试来看,\x 是一个无效的转义字符。

【问题讨论】:

【参考方案1】:

'/' 的前导和尾随字符更改为'"',然后将每个'\' 替换为"\\"

javascript、Perl 和其他脚本语言不同,Java 没有用于正则表达式的特殊语法。相反,它们(通常)使用 Java 字符串文字表示。但是'\' 是Java 字符串文字中的转义字符,因此原始正则表达式中的每个'\' 都必须使用第二个'\' 进行转义。 (如果你在正则表达式中有一个文字反斜杠字符,你最终会在 Java 字符串文字中得到"\\\\"!!)

这对于 Java 新手来说有点令人困惑/令人生畏,但这是完全合乎逻辑的。请记住,您使用的是 Java 字符串文字 来表达正则表达式。


然而,正如@antak 所说,Java 和 JavaScript 实现的正则表达式语言之间存在各种差异。因此,如果您采用任意 JavaScript 正则表达式并将其音译为 Java(如上所述),它可能无法正常工作。

这里有一些总结差异的参考资料。

https://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines https://gist.github.com/CMCDragonkai/6c933f4a7d713ef712145c5eb94a1816

【讨论】:

谢谢很多..我没有完全理解第二部分...将每个 '\' 替换为 '\' .....它们不一样吗? @testndtv - 我说“必须用第二个反斜杠转义”。我没有说它必须被替换。 如果它可以这么简单... Java 和 JS 中的正则表达式有细微的差异,会咬那些不知道的人:例如JS:'ab]cd'.replace(/[^]]/g, '()') -> a()cd,Java:"ab]cd".replaceAll("[^]]", "()") -> ()()]()()【参考方案2】:

您可以使用在线正则表达式评估器(如https://regex101.com)进行转换。

    转到https://regex101.com 选择ECMAScript (JavaScript) FLAVOR 插入您的正则表达式 打开TOOLS -> Code Generator (LANGUAGE - Java) 复制粘贴

即使它不是铁杆程序员的方式,但它的出错率要低得多。 特别是如果您只需要转换一两个表达式。

【讨论】:

我盯着一些很长的 JS 正则表达式并将 NPM 模块重新编程为一个 Java 包......我小心翼翼地逃离了转义逃逸以逃避我的头痛......在这次逃跑结束时,这个答案帮助我摆脱了我的转义序列已经逃脱了一些编码转义逻辑的疑虑!【参考方案3】:

如果您真的需要 Java 中的 Javascript 正则表达式语义,一种方法是使用嵌入式 Javascript 引擎来评估正则表达式。例如:

javax.script.ScriptEngineManager se = new javax.script.ScriptEngineManager();
javax.script.ScriptEngine engine = se.getEngineByName("js");

String regExp = "/^\\d+$/";
engine.put("str", "1234");
engine.eval("var rgx=" + regExp);
Object value = engine.eval(
    "function validate(r, s) return (r).test(s);;validate(rgx, str);");
logger.log(value);

【讨论】:

【参考方案4】:

您唯一需要做的就是复制反斜杠。

Pattern p1 = Pattern.compile("[a-zA-Z]");
Pattern p2 = Pattern.compile("[0-9]|[\\x21-\\x2F|\\x3A-\\x40|\\x5B-\\x60|\\x7B-\\x7E]");

if (p1.matcher(str).find() && p2.matcher(str).find()) 
    return true;

【讨论】:

@testndtv:永远不要在不显示错误消息的情况下说您收到错误。 它缺少第二个find() 调用;立即尝试。 再次感谢...实际上我用 .matches() 替换了我希望也应该没问题...请确认..【参考方案5】:

Java 正则表达式首先是字符串,因此您必须以双引号而不是/ 开头。此外,在 java 中,您需要通过像 \\ 那样执行其中两个来转义 \

查看来自 Oracle 的 this 教程以获取更多信息。

【讨论】:

这不是正则表达式引擎本身,而是matches() 方法要求正则表达式消耗整个字符串,就好像它被锚定在两端一样。 find() 方法执行更传统的匹配,但您不能像使用 matches() 那样从 String 对象调用它;您必须显式创建一个 Matcher 对象,例如 AlexR did。 @AlanMoore:感谢您告诉我。我很少用 find,我几乎一直用matches()。我已从我的回答中删除了该部分,再次感谢您的澄清。【参考方案6】:

如果您想在 Javascript 和 Java 中使用相同的正则表达式,请尝试在运行时获取正则表达式字符串,而不是尝试在编译时定义正则表达式。在编译时它会检查语法,它会给你无效的转义字符错误,但是在运行时它不会检查语法,而是直接编译模式。

如果您可以从 API 获取正则表达式或可以从本地存储的文本文件中读取它,那就太好了。

【讨论】:

以上是关于将 Javascript 正则表达式转换为 Java 语法的主要内容,如果未能解决你的问题,请参考以下文章

将 c# 正则表达式转换为 javascript 正则表达式

将 po box javascript 正则表达式转换为 c# 正则表达式

正则表达式 - 将 C# 正则表达式转换为 JavaScript 正则表达式的量词的目标无效

将 Javascript 正则表达式转换为 PHP

将 Javascript 正则表达式转换为 Java 语法

反斜杠 - 正则表达式 - Javascript