在回答另一个问题时,我编写了一个正则表达式来匹配所有空格,最多包括一个换行符。我对换行符匹配器使用负查找来完成此操作:
((?<!\R)\s)*
后来我想了想,我说,哦,不,如果有一个\r\n?它肯定会抓取第一个断行字符,然后我会被下一个字符串前面的伪字符卡住,对吗?
所以我回去测试(大概是修复)它。然而,当我测试该模式时,它匹配了整个\r\n
。它不仅匹配\r
,还留下\n
正如人们所期望的那样。
"\r\n".matches("((?<!\\R)\\s)*"); // true, expected false
但是,当我使用文档中提到的“等效”模式时,它返回false。那么,这是Java的一个bug,还是有一个与之匹配的正当理由?
实现#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应该说:
。。。相当于(?
根据Sherman在Oracle JDK-8176029上于2017年3月9日更新:
“api文档没有错误,实现错误(当”0x0d 0x0a next“时,无法回溯”0x0d next.match()”。match()“失败)”
认识#2。回头看不仅仅是向后看
尽管有这个名字,一个lookback不仅能够向后看,而且可以包括甚至跳过当前位置。
考虑以下示例(来自rexegg.com):
"_12_".replaceAll("(?<=_(?=\\d{2}_))\\d+", "##"); // _##_
“这很有意思,有几个原因。首先,我们在“向后看”中有一个“向前看”,即使我们应该向后看,这个“向前看”通过匹配两个数字和后面的下划线跳过当前位置。这很有技巧。”
这对于我们的示例来说意味着,即使我们的当前位置可能是,这也不会阻止后面的人识别出它的\R
后面紧跟着\R
,然后将两者作为一个原子组绑定在一起,从而拒绝将当前位置后面的部分识别为单独的匹配。
注意:为了简单起见,我使用了诸如“我们当前的位置是”之类的术语,但是这并不是内部发生的情况的精确表示。
构造\R
是一个宏,它将子表达式包围成一个原子组(?
这就是为什么它不会把他们分开。
注意:如果Java在lookbehind中接受固定的替换,那么可以使用
\R
,但如果引擎不接受,则会引发异常。
问题内容: 在回答另一个问题时,我写了一个正则表达式来匹配所有空格,最多不超过一个换行符。我为换行匹配器使用了负向后看: 之后我想了一下,我说,哦,不,如果有?它肯定会抢到第一个换行符,然后在下一个字符串的前面我会被一个假的东西卡住,对吗? 所以我回去测试(大概修复)它。但是,当我测试模式时,它与整个匹配。它不匹配只是留下正如人们所预料。 然而,当我使用中提到的“等价物”模式文档的,它返回fals
问题内容: 我有这种模式: 这对于正数很好用,但是我也需要它做负数,例如“ T-1T3T44”应该工作。或者也许使用空格而不是’T’,所以它应适用于这样的字符串:“-1 2 3 2 -1 6 2”。抱歉,我以前没有真正使用过正则表达式。有什么建议吗?谢谢。 问题答案: 您是否想过尝试: 您会注意到我也将(零个或多个)更改为(一个或多个),因为从技术上讲,这不是数字:-)
问题内容: 我正在尝试输入之间的内容,我的模式没有做正确的事,请帮忙。 下面是sudocode: 要求的输出: 之一 二 三 问题答案: 先行使用并在循环中使用,而不是: 看到它在线上工作:ideone 但是最好在这里使用split: 看到它在线上工作:ideone
主要内容:正则表达式支持字符正则表达式(Regular Expression)又称正规表示法、常规表示法,在代码中常简写为 regex、regexp 或 RE,它是计算机科学的一个概念。 正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作,是一种可以用于模式匹配和替换的规范。一个正则表达式就是由普通的字符(如字符 a~z)以及特殊字符(元字符)组成的文字模式,它用以描述在查找文字主体时待匹配的
问题内容: 我需要这件事的帮助。查看以下正则表达式: 我想查找这样的词:“自制”,“ aaaa-bbb”而不是“ aaa-bbb”,而 不是 “ aaa–aa–aaa”。基本上,我想要以下内容: 单词-连字符-单词。 它适用于所有内容,但该模式会通过:“ aaa–aaa–aaa”,但不应通过。哪种正则表达式适用于此模式? 问题答案: 可以从表达式中删除反斜杠: 下面的代码应该工作 请注意,您可以使
问题内容: 用java 方法剥离输入的字符串(如MY-CORP \ My.Name)中的MY-CORP \部分的正则表达式是什么,这样我只能得到My.Name部分? 我试过了 但是我 在索引4 ^附近 遇到了 意外的内部错误。 * 问题答案: 您的问题是反斜杠在Java字符串和正则表达式中都有特殊含义。因此,您需要在Java源代码中使用四个斜杠,将两个斜杠传递给regex解析器以在regex中获得