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

IT技术 java javascript regex matcher
2021-03-07 18:36:05

我知道 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 是一个无效的转义字符。

6个回答

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

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

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


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

以下是一些总结差异的参考资料。

要是它可以这么简单就好了……Java 和 JS 中的正则表达式有细微的差别,会咬那些不知道的人:例如 JS: 'ab]cd'.replace(/[^]]/g, '()')-> a()cd,Java: "ab]cd".replaceAll("[^]]", "()")->()()]()()
2021-04-26 18:36:05
Thx很多..我不太明白第二部分......用'\'替换每个'\'......它们都不一样吗?
2021-04-30 18:36:05
@testndtv -我说:“必须要躲过了第二个反斜杠”。我没说必须换。
2021-05-20 18:36:05

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

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

即使它不是硬核程序员的方式,它也明显不太容易出错。特别是如果您只需要转换一两个表达式。

我一直盯着一些很长的 JS 正则表达式,然后将该 NPM module重新编程到一个 Java 包中……我小心翼翼地避开了转义转义以逃避我的头痛……在这次转义结束时,这个答案帮助我摆脱了我的疑虑我的转义序列已经转义了一些编码转义逻辑!
2021-04-25 18:36:05

如果您真的需要 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);

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

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;
}
再次感谢...实际上我用 .matches() 替换了,我希望它也应该没问题...请确认...
2021-04-27 18:36:05
@testndtv:永远不要在不显示错误消息的情况下说你收到了错误。
2021-05-04 18:36:05
它错过了第二个find()电话;现在就试试。
2021-05-07 18:36:05

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

有关更多信息,请查看Oracle 的教程。

它不是正则表达式引擎本身,而是matches()需要正则表达式消耗整个字符串的方法,就好像它被锚定在两端一样。find()方法执行更传统的匹配类型,但您不能像使用matches();那样从 String 对象调用它你必须像AlexR 那样显式地创建一个 Matcher 对象
2021-04-28 18:36:05
@AlanMoore:谢谢你让我知道。我很少使用 find,我几乎总是使用matches(). 我已从答案中删除了该部分,再次感谢您的澄清。
2021-05-04 18:36:05