Что происходит с этим странным поведением при использовании |внутри ()? - PullRequest
0 голосов
/ 30 января 2019

Я работаю над паттерном Regex, который вызывает у меня головную боль.После сужения проблемы я столкнулся со странным поведением, которое я не понимаю:

Под шаблон, который я хотел использовать в первую очередь

\.(\d|\d\d)

недайте мне полное совпадение, когда я предоставлю тестовую строку ".20", только частичное совпадение ".2".Однако, когда я переворачиваю его,

(\d|\d\d)\.

дает мне полное совпадение «20».когда я предоставляю тестовую строку "20."Я не понимаю, откуда происходит это противоположное поведение, это довольно просто.Или .+ 1 цифра или.+ 2 цифры.Я не использую ^ ни $, в качестве тестовой строки я пробовал это с ".20", как есть, или похоронен в каком-то другом тексте.

Что здесь происходит?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Вы не указали, какой движок регулярных выражений вы используете и как, но сопоставители регулярных выражений не обязательно пытаются сопоставить шаблон с входом целом или найти самое длинное совпадение.Как правило, они удовлетворены тем, что нашли любое совпадение, и, если возможно несколько, то какое из них сопоставляется, зависит от двигателя.Имея это в виду, обратите внимание, что начальная .2 подстрока вашего ввода действительно может быть сопоставлена ​​с шаблоном, используя однозначную альтернативу шаблона.

Ваш второй пример, возможно, может соответствовать просто 0. а не вся строка.Тот факт, что он соответствует всей строке, является функцией реализации движка regex, или того, как вы его используете, или и того, и другого.

Если вы хотите, чтобы шаблон соответствовал всему вводу (илииначе совсем не совпадают), тогда якорь это:

^(\.(\d|\d\d))$

В большинстве диалектов регулярных выражений вы встретите, ^ соответствует началу (нулевой ширины) начала ввода илиодна строка ввода, и, аналогично, $ соответствует концу.

0 голосов
/ 30 января 2019

Когда вы предоставляете строку .20 регулярному выражению \.(\d|\d\d), \. в регулярном выражении соответствует . в строке.Затем он пытается сопоставить левую сторону |, т. Е. \d с 2, что также успешно.Поскольку левая сторона | была сопоставлена, он не будет пытаться сопоставить правую сторону |.Следовательно, у нас есть финальный матч 0.2.Если бы регулярное выражение было чем-то вроде \.(\d\d|\d), то при вводе 0.20 вы бы получили полное совпадение 0.20.

Когда вы предоставляете 20. регулярному выражению (\d|\d\d)\., оно сначаласоответствует левой части |, т. е. \d с номером 2.Поскольку левая сторона | полностью соответствует, она не пытается сопоставить правую сторону |.Теперь он пытается сопоставить \. с цифрой 0, что, конечно, не удается.Из-за сбоя происходит возврат и теперь правая часть |, то есть \d\d сопоставляется с 20, а затем \. сопоставляется с ..Следовательно, вы получите полное совпадение 20.

...