В чем разница между.* ? и.* регулярные выражения?
Я пытаюсь разделить строку на две части с помощью 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 матчей.*далее следует следующее выражение.первое выражение
<(.*)>не останавливается при сопоставлении первого>. Он будет продолжаться до последнего матча>.