匹配字符串的正则表达式 - 正向前瞻

时间:2012-01-07 13:22:12

标签: regex lookahead regex-lookarounds

Regexp:(?=(\d+))\w+\1 字符串:456x56

您好,

我没有得到这个概念,这个正则表达式如何匹配字符串“456x56”中的“56x56”。

  1. 环视,(?=(\ d +)),捕获456并放入\ 1,用于(\ d +)
  2. 字符“\ w +”匹配整个字符串(“456x56”)
  3. \ 1,即456,后跟\ w +
  4. 在回溯字符串后,它找不到匹配项,因为没有“456”前面有一个单词字符

然而正则表达式匹配56x56。

5 个答案:

答案 0 :(得分:7)

5)正则表达式引擎断定如果它从4开始搜索就无法找到匹配项,因此它会跳过一个字符并再次搜索。这一次,它会将两位数字捕获到\1,最后匹配56x56

如果您只想匹配整个字符串,请使用^(?=(\d+))\w+\1$

^ matches beginning of string
$ matches end of string

答案 1 :(得分:6)

正如已经说过的那样,你并没有固定你的正则表达式。另一个问题是\w也匹配数字...现在看一下正则表达式引擎如何与你的输入匹配:

# begin
regex: |(?=(\d+))\w+\1
input: |456x56
# lookahead (first group = '456')
regex: (?=(\d+))|\w+\1
input: |456x56 
# \w+
regex: (?=(\d+))\w+|\1
input: 456x56|
# \1 cannot be satisfied: backtrack on \w+
regex: (?=(\d+))\w+|\1
input: 456x5|6 
# And again, and again... Until the beginning of the input: \1 cannot match
# Regex engine therefore decides to start from the next character:
regex: |(?=(\d+))\w+\1
input: 4|56x56
# lookahead (first group = '56')
regex: (?=(\d+))|\w+\1
input: 4|56x56
# \w+
regex: (?=(\d+))\w+|\1
input: 456x56|
# \1 cannot be satisfied: backtrack
regex: (?=(\d+))\w+|\1
input: 456x5|6
# \1 cannot be satisfied: backtrack
regex: (?=(\d+))\w+|\1
input: 456x|56
# \1 satified: match
regex: (?=(\d+))\w+\1|
input: 4<56x56>

答案 2 :(得分:0)

你列出的几乎完全,但并不完全错误!

 1) The group  (?=(\d+)) matches a sequence of one or more digits
    not necessarily 456 
 2) \w captures only characters, not digits 
 3) \1 the is a back reference to the match in the group

因此,角色表达式意味着找到一个数字序列,后跟s字符序列,后面跟着在字符前面找到的相同序列。因此比赛56x56。

答案 3 :(得分:0)

那就是让它成为积极前瞻的原因

 (?=(\d+))\w+\1

当你说第一个\ d +将匹配456时你是正确的,所以\ 1也必须是456,但如果是这样的话:表达式将与字符串不匹配。

在x之前和x之后的唯一常见字符是56,这就是它将如何获得正匹配。

答案 4 :(得分:0)

操作员+贪婪并根据需要回溯。如果正则表达式失败,前瞻(?=(\d+))将匹配456然后56匹配,如果正则表达式失败则前瞻6。第一次尝试:456。它匹配,组1包含456.然后我们\w+贪婪并且需要456x56,没有剩下但我们仍然需要匹配\1即456.因此:失败。然后\w+一次一步地回溯,直到我们到达正则表达式的开头。它仍然失败。

我们从字符串中消耗一个字符。下一个backtrack试图与子串56进行超前匹配。它匹配,组1包含56. \w+匹配直到字符串结束并得到456x56然后我们尝试匹配56:失败。所以\w+直到我们在字符串中剩下56个然后我们才有全局匹配和正则表达式成功。

您应该使用regex buddy调试模式进行尝试。