Lookbehind与Ruby正则表达式中的^字符

时间:2013-06-24 18:00:19

标签: ruby regex

为什么在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">

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

6 个答案:

答案 0 :(得分:5)

后视模式(?<=ID: )匹配前面带有«ID: »的字符串中的位置

主播^\A在行或字符串的开头匹配位置

因此模式\A(?<=ID: )要求两者一起匹配,即字符串的开头前面有«ID: »。不会发生!

答案 1 :(得分:4)

如果你把锚放在lookbehind中,这两个都可以正常工作:

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

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

答案 2 :(得分:2)

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

例如,第一个表达式相当于另一种写作方式:/^\d+/(它以\d+为前提,不以空格开头,但这是不可能的,因为^之前不能有任何内容1}}无论如何)。

答案 3 :(得分:1)

在第三个表达式中,lookbehind可以在任何地方发生,特别是在4之前的零宽度空间中。您可以看到only the 4 is matched

使用^\A时,字符串开头的零宽度空间必须与lookbehind匹配,这是不可能的。

答案 4 :(得分:1)

  • regex1 /^(?<=ID: )\d+/中,必须有以ID:开头的行的开头。有问题的字符串没有这一点。

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

  • regex3 /(?<=ID: )\d+/中,必须有一个以ID:开头的字符串,后跟\d+。字符串中有这样的一点。

答案 5 :(得分:0)

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

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

ID: 4
    ^