Lookaround Regex engine - PullRequest
       1

Lookaround Regex engine

1 голос
/ 20 января 2011

Как работает механизм регулярных выражений с точки зрения внешнего вида? мой конкретный запрос следующий:

Если я наберу ^(?!ABC)$, будет ли он просматривать всю строку для подстроки ABC?

Во-вторых, как мне выполнить две операции в одном регулярном выражении? Скажем, я хотел найти строку с нечетным числом b и четным числом c?

РЕДАКТИРОВАТЬ: я хочу говорить только о регулярных выражениях; Я знаю, что это можно сделать другими способами.

Это то, что я использую:

\b(?=[^A]*A([^A]*A[^A]*A)*[^A]*)([^C]*(C[^C]*C[^C]*)*[^C]*)\b

Сбой на CC, но должен извлекать строки только с нечетными a и c.

Ответы [ 4 ]

1 голос
/ 21 января 2011

Оказывается, вы можете сделать это с помощью регулярного выражения ванили. Это просто не красиво.

^((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*(b|c((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*b((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*c)((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*$

Чтобы понять регулярное выражение, нарисуйте DFA с четырьмя состояниями, расположенными в квадрате, связанном вперед и назад по периметру квадрата. Горизонтальные ссылки представляют потребление B, в то время как вертикальные ссылки представляют потребление C. В верхнем левом углу находится начальное состояние, представляющее наличие четного числа Cs и четного числа Bs. В верхнем правом углу находится состояние принятия, достигаемое путем использования B. Нижние состояния достигаются из верхних состояний (и наоборот) путем использования C. Теперь мы можем сделать любое количество переходов, которые сохраняют паритет наших C и Bs, и мы вернемся в исходное состояние. Затем мы потребляем B, приводя нас в наше состояние принятия. Тогда оттуда, пока мы поддерживаем паритеты, у нас все хорошо. Два C поддерживают паритет, как и два B. Это бит (cc|bb)*.

Но вы также можете сохранить паритет, перейдя в противоположный угол (через C и B в любом порядке), выполнив столько BB / CC, сколько захотите, а затем вернувшись в тот угол, в котором вы были (опять же, в любом случае). ). Вот этот бит: ((bc|cb)(bb|cc)*(bc|cb))*

Итак, у нас есть ((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*, представляющий собой набор переходов, которые возвращают нас туда, где мы начали (назовем это noop). Вы можете сделать свой нечетный переход B на вершине, в этом случае подойдет b, или внизу, и в этом случае вам нужно спуститься на дно с помощью c, сделать еще один noop, затем сделать ваш b, затем еще один noop, затем c обратно наверх.

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

1 голос
/ 20 января 2011

^ (?! ABC) $ будет ли просматриваться строка для подстроки ABC?

Нет, она соответствует только пустой строке, она нулевой ширины негативный взгляд.Вы можете использовать его для таких вещей, как "^(?!ABC)A..$", соответствующих ABD, ADC, но не ABC.

Во-вторых, как мне выполнить две операции в одном регулярном выражении?Скажем, я хотел найти строку с нечетным числом b и четным числом c?

Напишите два шаблона и положите первый из них в положительном виде, например (?=pat1)pat2

0 голосов
/ 20 января 2011

Нечетный шаблон c будет выглядеть так: ^[^c]*c[^c]*(c[^c]*c)*[^c]*$ Не очень хороший, и если вы захотите добавить к нему шаблон четного b ^[^b]*(b[^b]*b)*[^b]*$, результат будет практически не читаем.

0 голосов
/ 20 января 2011

Регулярное выражение будет соответствовать только пустым строкам.

Регулярное выражение, вероятно, не лучший вариант, если вы хотите найти количество нечетных / четных c и b.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...