В чем разница между.* ? и.* регулярные выражения?
Я пытаюсь разделить строку на две части с помощью regex. Строка имеет следующий формат:
text to extract<number>
Я использую (.*?)<
и <(.*?)>
которые работают нормально, но после чтения в регулярное выражение немного, я только начал задаваться вопросом, зачем мне нужен ?
в выражениях. Я сделал это только после того, как нашел их на этом сайте, поэтому я не совсем уверен, в чем разница.
3 ответа:
это разница между жадными и не жадными кванторами.
рассмотреть вход
101000000000100
.используя
1.*1
,*
жадный - он будет соответствовать весь путь до конца, а затем вернуться, пока он не может соответствовать1
С1010000000001
..*?
не жадный.*
не будет соответствовать ничего, но затем будет пытаться соответствовать дополнительные символы, пока он не соответствует1
в итоге сопоставления101
.все кванторы имеют a не жадный режим:
.*?
,.+?
,.{2,6}?
, и даже.??
.в вашем случае аналогичная картина может быть
<([^>]*)>
- соответствие чему-либо, кроме знака больше, чем (строго говоря, он соответствует нулю или более символов, отличных от>
между<
и>
).посмотреть Квантор Шпаргалка.
на жадных против не-жадных
повторение в регулярном выражении по умолчанию жадина: они стараются соответствовать как можно большему количеству повторений, и когда это не работает, и им приходится отступать, они пытаются соответствовать одному меньшему повторению за раз, пока не будет найдено совпадение всего шаблона. В результате, когда матч, наконец, происходит, жадное повторение будет соответствовать как много повторений, как это возможно.
The
?
как Квантор повторения изменяет это поведение в нежадный, также называемый хочет (например, Java) (а иногда и "ленивый"). Напротив, это повторение сначала попытается соответствовать как несколько повторений, как это возможно, и когда это не работает, и они должны вернуться, они начинают соответствовать еще один репт время. В результате, когда матч, наконец, происходит, неохотное повторение будет соответствовать как несколько повторений, как вероятный.ссылки
Пример 1: от A до Z
давайте сравним эти две модели:
A.*Z
иA.*?Z
.учитывая следующие данные:
eeeAiiZuuuuAoooZeeee
шаблоны дают следующие совпадения:
A.*Z
дает 1 матч:AiiZuuuuAoooZ
(посмотреть на rubular.com)A.*?Z
дает 2 матча:AiiZ
иAoooZ
( смотрите дальше rubular.com)давайте сначала сосредоточимся на том, что
A.*Z
делает. Когда он соответствовал первомуA
на.*
, будучи жадным, сначала пытается соответствовать, как много.
как это возможно.eeeAiiZuuuuAoooZeeee \_______________/ A.* matched, Z can't match
с
Z
не совпадает, двигатель отступает, и.*
тогда должно совпадать на один меньше.
:eeeAiiZuuuuAoooZeeee \______________/ A.* matched, Z still can't match
этот происходит еще несколько раз, пока, наконец, мы не приходим к этому:
eeeAiiZuuuuAoooZeeee \__________/ A.* matched, Z can now match
теперь
Z
может соответствовать, поэтому общая картина соответствует:eeeAiiZuuuuAoooZeeee \___________/ A.*Z matched
напротив, неохотное повторение в
A.*?Z
первые матчи, как несколько.
насколько это возможно, а затем принимать больше.
по мере необходимости. Это объясняет, почему он находит два совпадения на входе.вот визуальное представление того, что эти два шаблона соответствуют:
eeeAiiZuuuuAoooZeeee \__/r \___/r r = reluctant \____g____/ g = greedy
пример: Альтернатива
во многих приложениях два совпадения в приведенном выше входе-это то, что требуется, поэтому неохотно
.*?
используется вместо жадного.*
чтобы предотвратить пересечение. Однако для этого конкретного шаблона есть лучшая альтернатива, используя отрицательный класс символов.шаблон
A[^Z]*Z
также находит те же два совпадения, что иA.*?Z
шаблон для указанного выше ввода (как видно на ideone.com).[^Z]
это то, что называется a отрицается класс символов: он соответствует чему угодно, ноZ
.основное различие между двумя шаблонами заключается в производительности: будучи более строгим, отрицаемый класс символов может соответствовать только одному способу для данного ввода. Не имеет значения, используете ли вы жадный или неохотный модификатор для этого шаблона. На самом деле, в некоторых вкусах вы можете сделать еще лучше и использовать то, что называется притяжательным квантором, который не отступает все.
ссылки
- regular-expressions.info/Repetition -альтернатива лени, Отрицаемые Классы Символов и Притяжательные Квантификаторы
Пример 2: от A до ZZ
этот пример должен быть иллюстративным: он показывает, как жадные, неохотные и отрицательные шаблоны классов символов совпадают по-разному, учитывая одно и то же вход.
eeAiiZooAuuZZeeeZZfff
это совпадения для приведенного выше ввода:
A[^Z]*ZZ
дает 1 матч:AuuZZ
(как видно на ideone.com)A.*?ZZ
дает 1 матч:AiiZooAuuZZ
(как видно на ideone.com)A.*ZZ
дает 1 матч:AiiZooAuuZZeeeZZ
(как видно на ideone.com)вот визуальное представление того, что они соответствует:
___n / \ n = negated character class eeAiiZooAuuZZeeeZZfff r = reluctant \_________/r / g = greedy \____________/g
связанные разделы
это ссылки на вопросы и ответы на stackoverflow, которые охватывают некоторые темы, которые могут представлять интерес.
одно жадное повторение может outgreed другое
допустим, у вас есть:
<a></a>
<(.*)>
матчa></a
где<(.*?)>
будет соответствоватьa
. Последний останавливается после первого матча>
. Он проверяет для одного или 0 матчей.*
далее следует следующее выражение.первое выражение
<(.*)>
не останавливается при сопоставлении первого>
. Он будет продолжаться до последнего матча>
.