Java 匹配与 JavaScript 匹配之间的结果差异

Posted

技术标签:

【中文标题】Java 匹配与 JavaScript 匹配之间的结果差异【英文标题】:Difference in results between Java matches vs JavaScript match 【发布时间】:2014-03-19 23:15:16 【问题描述】:

当我做一个简单的测试时,我正在复习我在 java 中的正则表达式

Pattern.matches("q", "Iraq"); //false
"Iraq".matches("q"); //false

但在 javascript

/q/.test("Iraq"); //true
"Iraq".match("q"); //["q"] (which is truthy)

这里发生了什么?我可以让我的 Java 正则表达式模式“q”的行为与 JavaScript 相同吗?

【问题讨论】:

请不要仅仅根据名称来比较两种不同语言的方法。而是去看看各自的文档。 我发现它匹配整个字符串,但是除了“有关正则表达式构造行为的更精确描述,请参阅 Mastering Regular Expressions, 3nd Edition, Jeffrey 之外,java 没有任何文档EF Friedl,O'Reilly and Associates,2006 年。” 你引用的句子前面有不少于 9 屏对 Java 正则表达式语法和语义的详细阐述。 当然,这只是类文档,您调用的特定方法的文档指向:Attempts to match the entire region against the pattern. 好吧,我发现它不是在 Pattern 上,而是在(显然)Matcher 的页面上 - matches 方法尝试将整个输入序列与模式匹配... 【参考方案1】:

在 JavaScript 中 match 返回匹配使用的正则表达式的子字符串。在 Java 中,matches 检查整​​个字符串是否与正则表达式匹配。

如果您想查找匹配正则表达式的子字符串,请使用 Pattern 和 Matcher 类,例如

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(yourData);
while(m.find())
   m.group();//this will return current match in each iteration
   //you can also use other groups here using their indexes
   m.group(2);
   //or names (?<groupName>...)
   m.group("groupName");

【讨论】:

这就是我想要的。一种绕过默认 matches 行为的方法。 这正是我想要的 @jermel 和 Michael Perrenoud:很高兴你喜欢它 :)【参考方案2】:

这是因为在 Java 中 Pattern#matchesString#matches 期望您匹配完整的输入字符串,而不仅仅是其中的一部分。

另一方面,正如您在示例中看到的那样,Javascript 的 String#match 可以部分匹配输入。

【讨论】:

如果我理解正确,它只是一个不同的引擎 - 时期。它们在 Java、Ruby、JavaScript、Python、.NET 等之间的工作方式不同 - 对吧? 是的,这是真的。此方法的 Java 的 matches 名称也会引起很多混乱。 在 Java 中是否有一个 switch 可以防止它被前缀和后缀开头和结尾字符? 顺便说一句:Python 也有 re.match()re.search()。第一个_match_es从头到尾的整个字符串,第二个_search_es如果找到字符串 在 Java 中需要这样做:Pattern.matches(".*?q.*", "Iraq"); 或者最好使用 Pattern#find() 方法,该方法用于部分匹配。【参考方案3】:

在 JavaScript 中,String.match 查找部分匹配项。在 Java 中,如果整个输入字符串与给定模式匹配,Pattern.matches 将返回 true。这相当于说,在您的示例中,“伊拉克”应该匹配 ^q$,但显然不匹配。

这里来自Java's Matcher Javadoc(注意Pattern.matches在内部创建了一个Matcher然后调用matches):

public boolean matches()

尝试将整个区域与模式匹配。如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。

返回:当且仅当整个区域序列与此匹配器的模式匹配时才为真

如果您只想测试字符串的一部分,请在正则表达式的开头添加.*?,并在末尾添加.*,例如Pattern.match("iraq", ".*?q.*")

请注意,.*q.* 也可以,但如果输入字符串很长,则使用前面的不情愿运算符可能会显着提高性能。请参阅this answer 了解不情愿和贪婪运算符之间的区别以及它们对回溯的影响以进行解释。

【讨论】:

:-) 这句话来自 Matcher 的 javadoc @jermel 确实如此。固定。

以上是关于Java 匹配与 JavaScript 匹配之间的结果差异的主要内容,如果未能解决你的问题,请参考以下文章

javascript正则表达式匹配两个字符串之间的所有内容(没有换行符)[重复]

来自 typescript/javascript 的 JSON.stringify 与 Java 控制器中的 json-String param/request-body 不匹配

javascript 能够扫描文本并查找单词之间的匹配点,以提取语法

证书与私钥匹配

JavaScript正则表达式可重复字符串中的元素匹配

javascript 正则表达式之分组与前瞻匹配详解