Упорядочивание предвидения Regex

Я довольно достоин с регулярными выражениями, и теперь я пытаюсь еще раз понять предвидение и lookbehind утверждения. Они главным образом имеют смысл, но я не совсем уверен, как порядок влияет на результат. Я смотрел на этот сайт, который помещает lookbehinds перед выражением и предвидениями после выражения. Мой вопрос, это изменяет что-нибудь? Недавний ответ здесь на ТАК помещенном предвидение перед выражением, которое является ведущим к моему беспорядку.

6
задан David Kanarek 24 January 2010 в 06:03
поделиться

3 ответа

Когда учебные пособия вводят поиск, они, как правило, выбирают самый простой вариант использования для каждого из них. Поэтому они будут использовать такие примеры как (? ('b' не предшествует 'a') или q(?=u) ('q', за которым следует 'u'). Это просто для того, чтобы не загромождать объяснение отвлекающими деталями, но это имеет тенденцию создавать (или усиливать) впечатление, что lookbehinds и lookaheads должны появляться в определенном порядке. Мне понадобилось довольно много времени, чтобы смириться с этой идеей, и я видел несколько других, которые тоже были этим затронуты.

Попробуйте взглянуть на более реалистичные примеры. Один из вопросов, который часто возникает, это проверка пароля; например, удостовериться, что новый пароль состоит как минимум из шести символов и содержит как минимум одну букву и одну цифру. Одним из способов сделать это может быть:

^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{6,}$

Символьный класс [A-Za-z0-9]{6,} может соответствовать всем буквам или всем цифрам, поэтому вы используете бланки просмотра, чтобы убедиться, что в пароле есть хотя бы по одной из них. В этом случае вы должны сначала сделать заголовки }, потому что более поздние части регекса должны быть способны исследовать всю строку.

Например, предположим, что необходимо найти все вхождения слова "там", если только ему не предшествует кавычки. Очевидным регексом для этого является (?, но если вы ищете большой корпус, то это может создать проблему с производительностью. Как написано, этот регекс сделает отрицательный взгляд на каждую позицию в тексте, и только тогда, когда это удастся, он проверит остальную часть регекса.

У каждого регекс-двигателя есть свои сильные и слабые стороны, но одно верно для всех из них - они быстрее находят фиксированные последовательности буквальных символов, чем что-либо другое - чем дольше последовательность, тем лучше. Это означает, что можно значительно быстрее сделать lookbehind last, хотя это означает двойное совпадение слова:

[Tt]here\b(?<!"[Tt]here)

Так что правило, регулирующее размещение lookaround'ов, заключается в том, что нет правила; вы помещаете их везде, где они имеют наибольший смысл в каждом случае.

9
ответ дан 8 December 2019 в 17:21
поделиться

1 (? = ABC) означает поиск 1 , а совпадение (но не захватывать) ABC после этого.
(? <= ABC) 1 означает матч (но не захватывать) ABC до текущего местоположения и продолжать совпадать 1 .
Так что, как правило, вы будете поместите полей после выражения и поиска перед ним.

Когда мы размещаем вид после выражения, мы перепроверяют строку, которую мы уже подобрали . Это распространено, когда у вас есть сложные условия (вы можете подумать об этом как в и Regexs). Например, посмотрите на этот недавний ответ Daniel Brückner :

.&.(?<! & )

Во-первых, вы захватите амперса и между двумя персонажами. Далее вы проверяете, что они не были пробелами ( \ S & \ S не будет работать здесь, OP хотел захватить 1 & _ ).

1
ответ дан 8 December 2019 в 17:21
поделиться

На примере легче показать, чем объяснить, я думаю. Давайте возьмем это Regex:

(?<=\d)(?=(.)\1)(?!p)\w(?<!q)

Что это значит:

  1. (? <= \ D) - Убедитесь, что то, что происходит до того, как положение совпадения является цифрой.
  2. (? = (.) \ 1) - Убедитесь, что любой символ, который мы совпадаем на этой (той же) положении, сопровождается копией самого себя (через Backreference).
  3. (?! P) - Убедитесь, что следует, что не является P .
  4. \ W - Сопоставьте букву, цифру или подчеркивание. Обратите внимание, что это первый раз, когда мы на самом деле сопоставляем и потребляем персонаж.
  5. (? - Убедитесь, что то, что мы до сих пор не заканчиваются Q .

Все это будет сопоставить строки, такие как abc5ddx или 9xx , но не 5d или 6QQ или ASD6PP или Добавить . Обратите внимание, что каждое утверждение работает независимо. Он просто останавливается, оглядывается, и, если все хорошо, позволяет совпадать, чтобы продолжить.

Обратите внимание также, что в большинстве (возможно всех) реализациях, внешний вид превышает ограничение фиксированной длины. Вы не можете использовать операторы повторения / дополнительных, таких как ? , * , а + в них. Это связано с тем, что для соответствия шаблону нам нужна отправная точка - в противном случае нам придется попробовать соответствовать каждому благу с каждой точки в строке.

Образец прогона этого регеляции на строке A3B5DDX следующим образом:

  1. Положение текстового курсора: 0.
    1. Постарайтесь сопоставить первое окно в позиции -1 (с \ D всегда совпадает с 1 символом). Мы не можем совпадать с отрицательными показателями, так что потерпите неудачу и продвигайте курсор.
  2. Положение текстового курсора: 1.
    1. Попробуйте сопоставить первое окно в позиции 0. A не совпадает \ D , поэтому выключите и продвиньте курсор снова.
  3. Текстовая позиция курсора: 2.
    1. Постарайтесь соответствовать первому взгляду в положении 1. 3 соответствует \ D , поэтому держите курсор в целом и продолжайте совпадение.
    2. Постарайтесь соответствовать первому lookahead в положении 2. B совпадения (.) (.) [) и захвачено. 5 не соответствует \ 1 (который является захваченным B ). Следовательно, терпят неудачу и продвигайте курсор.
  4. Текстовое положение курсора: 3.
    1. Постарайтесь соответствовать первому взгляду на позиции 2. B не совпадают \ D , поэтому выключите и продвиньте курсор снова.
  5. Положение текстового курсора: 4.
    1. Постарайтесь сопоставить первое окно в позиции 3. 5 . Соответствуйте \ d , поэтому сохраняйте курсор в целом и продолжайте соответствие.
    2. Постарайтесь соответствовать первому lookahead в положении 4. D совпадает (.) и захвачено. Второе d d соответствует \ 1 (который является первым захваченным D ). Разрешить соответствие продолжить, откуда мы остановились.
    3. Постарайтесь соответствовать второму lookahead. B в положении 4 не совпадает P , и поскольку это негативно, как мы хотим; Разрешить соответствие продолжить.
    4. Постарайтесь соответствовать \ W в положении 4. b совпадения. Проверьте курсор, поскольку мы потребляли персонажа и продолжаем. Также отметьте это как начало матча.
  6. Текстовая позиция курсора: 5.
    1. Постарайтесь сопоставить второе окно в позиции 4 (с Q всегда совпадает с 1 символом). D не совпадает Q , который мы хотим от негативного взгляда.
    2. Понимаем, что мы находимся в конце регулярного воздействия и докладываем успех, вернув подстроку от начала матча текущей позиции (4-5), что составляет d .
4
ответ дан 8 December 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: