6

Regexp: (?=(\d+))\w+\1 String: 456x56

Hi,

I am not getting the concept, how this regex matches "56x56" in the string "456x56".

  1. The lookaround, (?=(\d+)), captures 456 and put into \1, for (\d+)
  2. The wordcharacter, \w+, matches the whole string("456x56")
  3. \1, which is 456, should be followed by \w+
  4. After backtracking the string, it should not find a match, as there is no "456" preceded by a word character

However the regexp matches 56x56.

4

5 回答 5

7

5) 正则表达式引擎得出的结论是如果从 4 开始搜索就找不到匹配项,因此它会跳过一个字符并再次搜索。这一次,它捕获两个数字\1并最终匹配56x56

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

^ matches beginning of string
$ matches end of string
于 2012-01-07T13:26:10.950 回答
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>
于 2012-01-07T15:29:07.020 回答
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。

于 2012-01-07T13:28:38.293 回答
0

好吧,这就是使它成为积极展望的原因

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

当您说第一个 \d+ 将匹配 456 时,您是正确的,因此 \1 也必须是 456,但如果是这种情况:表达式将与字符串不匹配。

x 之前和 x 之后的唯一常见字符是 56,这就是获得肯定匹配的方法。

于 2012-01-07T13:29:32.263 回答
0

操作员+是贪婪的,并在必要时回溯。如果正则表达式失败,则前瞻(?=(\d+))将匹配 456,然后匹配 56,如果正则表达式失败,则匹配 6。第一次尝试:456。它匹配,组 1 包含 456。然后我们有\w+哪个是贪婪的,需要 456x56,什么都没有,但我们仍然必须匹配,\1即 456。因此:失败。然后\w+一次回溯一步,直到我们到达正则表达式的开头。它仍然失败。

我们使用字符串中的一个字符。下一个回溯尝试与子字符串 56 进行前瞻匹配。它匹配并且组 1 包含 56。\w+匹配到字符串末尾并获得 456x56,然后我们尝试匹配 56:失败。所以\w+回溯,直到我们在字符串中剩下 56 个,然后我们有一个全局匹配和正则表达式成功。

您应该尝试使用正则表达式伙伴调试模式。

于 2012-01-07T19:02:00.530 回答