当前位置: 首页 > 面试题库 >

Java-8正则表达式负数与\ R落后

敖硕
2023-03-14
问题内容

在回答另一个问题时,我写了一个正则表达式来匹配所有空格,最多不超过一个换行符。我为换行\R匹配器使用了负向后看:

((?<!\R)\s)*

之后我想了一下,我说,哦,不,如果有\r\n?它肯定会抢到第一个换行符\r,然后\n在下一个字符串的前面我会被一个假的东西卡住,对吗?

所以我回去测试(大概修复)它。但是,当我测试模式时,它与整个匹配\r\n。它不匹配只是\r留下\n正如人们所预料。

"\r\n".matches("((?<!\\R)\\s)*"); // true, expected false

然而,当我使用中提到的“等价物”模式文档的\R,它返回false。那是Java的错误,还是有匹配的有效理由?


问题答案:

实现#1。 该文档是错误的

来源:https
:
//docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

它说:

换行匹配器

…相当于 \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

但是,当我们尝试使用“等效”模式时,它将返回false:

String _R_ = "\\R";
System.out.println("\r\n".matches("((?<!"+_R_+")\\s)*")); // true

// using "equivalent" pattern
_R_ = "\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029]";
System.out.println("\r\n".matches("((?<!"+_R_+")\\s)*")); // false

// now make it atomic, as per sln's answer
_R_ = "(?>"+_R_+")";
System.out.println("\r\n".matches("((?<!"+_R_+")\\s)*")); // true

因此,Javadoc应该 真正 说:

…相当于 (?<!\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029])

根据Sherman在Oracle
JDK-8176029上
于2017年3月9日更新:

“ api doc没错,实现是错误的(当“ 0x0d + 0x0a + next.match()”失败时,它无法回溯“ 0x0d +
next.match()”)”

实现#2。 向后看不仅向后看

尽管有名称,但向后查找不仅可以向后看,而且可以包含甚至跳过当前位置。

考虑以下示例(来自rexegg.com):

"_12_".replaceAll("(?<=_(?=\\d{2}_))\\d+", "##"); // _##_

“这之所以有趣,有几个原因。首先,我们在回溯中有一个前瞻,即使我们应该向后看,该前瞻也会通过匹配两个数字和下划线来跳过当前位置。这是杂技。”

这对于我们的示例意味着什么\R,即使我们当前的位置可能是\n,也不会阻止后退者认识到其\r后面是\n,然后将两者绑定为一个原子团,因此拒绝识别其\r背后的部分。当前位置作为单独的匹配项。

注意:为简单起见,我使用了诸如“我们的当前位置是\n”之类的术语,但这并不是内部发生的事情的精确表示。



 类似资料:
  • 在回答另一个问题时,我编写了一个正则表达式来匹配所有空格,最多包括一个换行符。我对换行符匹配器使用负查找来完成此操作: 后来我想了想,我说,哦,不,如果有一个\r\n?它肯定会抓取第一个断行字符,然后我会被下一个字符串前面的伪字符卡住,对吗? 所以我回去测试(大概是修复)它。然而,当我测试该模式时,它匹配了整个。它不仅匹配,还留下正如人们所期望的那样。 但是,当我使用文档中提到的“等效”模式时,它

  • 本文向大家介绍PHP段落正则表达式,包括了PHP段落正则表达式的使用技巧和注意事项,需要的朋友参考一下 我经常发现有必要从博客文章的开头或类似内容中提取一段文字,以用作摘录。我通常使用一个函数,该函数将计算可用的整个单词的数量,并返回包含这些单词的字符串。 尽管仅当原始帖子为HTML时才适用,但这是一个很好的选择,那就是使用正则表达式提取内容。以下代码将使用字符串,并仅提取文本的第一段。 如果正则

  • 问题内容: 我有这种模式: 这对于正数很好用,但是我也需要它做负数,例如“ T-1T3T44”应该工作。或者也许使用空格而不是’T’,所以它应适用于这样的字符串:“-1 2 3 2 -1 6 2”。抱歉,我以前没有真正使用过正则表达式。有什么建议吗?谢谢。 问题答案: 您是否想过尝试: 您会注意到我也将(零个或多个)更改为(一个或多个),因为从技术上讲,这不是数字:-)

  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。

  • 问题内容: 我正在尝试输入之间的内容,我的模式没有做正确的事,请帮忙。 下面是sudocode: 要求的输出: 之一 二 三 问题答案: 先行使用并在循环中使用,而不是: 看到它在线上工作:ideone 但是最好在这里使用split: 看到它在线上工作:ideone

  • 主要内容:正则表达式支持字符正则表达式(Regular Expression)又称正规表示法、常规表示法,在代码中常简写为 regex、regexp 或 RE,它是计算机科学的一个概念。 正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作,是一种可以用于模式匹配和替换的规范。一个正则表达式就是由普通的字符(如字符 a~z)以及特殊字符(元字符)组成的文字模式,它用以描述在查找文字主体时待匹配的