2

为什么在 Ruby 中,前两个正则表达式不匹配,而第三个匹配?

str = 'ID: 4'
regex1 = /^(?<=ID: )\d+/
regex2 = /\A(?<=ID: )\d+/
regex3 = /(?<=ID: )\d+/

str.match(regex1)  # => nil
str.match(regex2) #=> nil
str.match(regex3) #=> #<MatchData "4">

唯一的区别是^or\A字符,它们分别匹配行的开头和字符串的开头。似乎两者都应该匹配str

4

6 回答 6

4

如果您将锚点放在后视中,这两种方法都可以正常工作:

regex1 = /(?<=^ID: )\d+/
regex2 = /(?<=\AID: )\d+/

如果锚点在后视之外,那么您说的是“从字符串的开头,是前面的字符ID:”。这总是会失败,因为在字符串开始之前不会有任何字符。

于 2013-06-24T18:04:02.067 回答
4

后视模式(?<=ID: )匹配字符串中以 . 开头的位置«ID: »

锚点^\A匹配行或字符串开头的位置。

所以该模式\A(?<=ID: )要求两者匹配在一起,即字符串的开头以«ID: ». 不会发生!

于 2013-06-24T18:12:32.700 回答
2

前瞻和后瞻是非捕获/零长度,因此前两个表达式不匹配。

例如,第一个表达式相当于另一种写作方式:(/^\d+/它的条件\d+是前面没有空格,但这是不可能的,因为^无论如何前面都不可能有任何东西)。

于 2013-06-24T18:03:37.317 回答
1

在第三个表达式中,lookbehind 可以出现在任何地方,特别是出现在4. 您可以看到只有4匹配

使用^or \A,字符串开头的零宽度空格必须与后向匹配,这是不可能的。

于 2013-06-24T18:05:00.860 回答
1
  • regex1中,即/^(?<=ID: )\d+/必须有一行开头,前面是ID:。有问题的字符串没有这样的意义。

  • regex2中,即/\A(?<=ID: )\d+/必须有一个以 开头的字符串的开头ID:。没有任何字符串具有这样的意义。

  • regex3中,即/(?<=ID: )\d+/必须有一个字符串点,其前面ID:和后面是\d+。字符串中有这样的点。

于 2013-06-24T18:05:33.390 回答
0

后视不会改变比赛的位置。

/(?<=ID: )\d+/实际上在数字处匹配:

ID: 4
    ^
于 2013-06-24T18:03:41.483 回答