为什么在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
匹配。
答案 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
^