Регулярное выражение, соответствующее строке - позитивный взгляд - PullRequest
6 голосов
/ 07 января 2012

Регулярное выражение: (?=(\d+))\w+\1 Строка: 456x56

Привет

Я не понимаю, как это регулярное выражение соответствует 56x56 в строке 456x56.

  1. Обход (? = (\ D +)) захватывает 456 и помещается в \ 1, для (\ d +)
  2. Символ слова, \ w +, соответствует всей строке ("456x56")
  3. \ 1, то есть 456, должно сопровождаться \ w +
  4. После возврата строки не должно быть совпадения, так как нет слова "456", которому предшествует символ слова

Однако регулярное выражение соответствует 56x56.

Ответы [ 5 ]

7 голосов
/ 07 января 2012

5) Механизм регулярных выражений заключает, что он не может найти совпадение, если он начинает поиск с 4, поэтому он пропускает один символ и ищет снова. На этот раз он захватывает две цифры в \1 и в итоге соответствует 56x56

Если вы хотите сопоставлять только целые строки, используйте ^(?=(\d+))\w+\1$

^ matches beginning of string
$ matches end of string
6 голосов
/ 07 января 2012

Вы не привязываете свое регулярное выражение, как уже было сказано. Другая проблема заключается в том, что \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>
0 голосов
/ 07 января 2012

Оператор + жадный и отступает по мере необходимости. Предварительный просмотр (?=(\d+)) будет соответствовать 456, а затем 56, если регулярное выражение не выполнено, и 6, если регулярное выражение не выполнено. Первая попытка: 456. Это соответствует, группа 1 содержит 456. Тогда у нас есть \w+, который является жадным и занимает 456x56, ничего не осталось, но мы все еще должны соответствовать \1, то есть 456. Таким образом: ошибка. Затем \w+ возвращается на один шаг за раз, пока мы не доберемся до начала регулярного выражения. И все равно не получается.

Мы потребляем символ из строки. Следующая обратная попытка пытается найти совпадение с подстрокой 56. Она совпадает, и группа 1 содержит 56. \w+ совпадений до конца строки и получает 456x56, а затем мы пытаемся сопоставить 56: неудача. Так что \w+ бактраков, пока у нас не останется 56 в строке, и тогда мы получим глобальное совпадение и успех регулярного выражения.

Вы должны попробовать это в режиме отладки regex buddy.

0 голосов
/ 07 января 2012

Ну, вот что делает его позитивным взглядом

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

Вы правы, когда говорите, что первое \ d + будет соответствовать 456, поэтому \ 1 также должно быть 456, но если это так: выражение не будет соответствовать строке.

Единственными распространенными символами до и после х являются 56, и это то, что он будет делать, чтобы получить положительное совпадение.

0 голосов
/ 07 января 2012

Точки, которые вы перечислили, почти полностью, но не совсем, неправильно!

 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 последовательности символов слова, за которыми следует та же последовательность, которая была найдена перед символами. Отсюда и совпадение 56х56.

...