2009-06-02 2 views
49

У меня есть механизм шаблонов python, который сильно использует regexp. Он использует конкатенацию как:Синтаксис регулярного выражения для "match nothing"?

re.compile(regexp1 + "|" + regexp2 + "*|" + regexp3 + "+") 

я могу изменять отдельные подстроки (regexp1, regexp2 и т.д.).

Есть ли какое-либо маленькое и легкое выражение, которое не соответствует ни одному, которое я могу использовать внутри шаблона, где мне не нужны совпадения? К сожалению, иногда к ядру regexp добавляется «+» или «*», поэтому я не могу использовать пустую строку - ошибка «ничего не повторится» будет расти.

+1

http://stackoverflow.com/questions/1723182/a-regex-that-will-never-be-matched-by-anything –

ответ

76

Это не должно ничего соответствовать:

re.compile('$^') 

Так что если вы замените regexp1, regexp2 и regexp3 с «$ ^» будет невозможно найти матч. Если вы не используете многолинейный режим.


После нескольких тестов я нашел лучшее решение

re.compile('a^') 

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

+0

Это не соответствует чему-либо точно и является легким для двигателя regexp для обработки? (не хочу, чтобы мои заглушки повторялись, чтобы съесть много процессора) – grigoryvp

+0

@Eye of hell. Он должен быть легким. Это попытается сопоставить конец строки, за которым следует начало строки. Это невозможно в одной строке. –

+1

Но возможно с несколькими линиями, конечно (в зависимости от того, включен ли флаг) - для решения, которое работает, включен ли флаг или нет, см. Мой ответ. –

3
"()" 

ничего не найдено и ничего не происходит.

+0

Это будет соответствовать пустой строке. Это зависит от того, что просит @ Eye of Hell. Если он вообще не хочет матча, это не сработает. –

+3

Nope - это соответствует чему угодно, но считается плохим шаблоном во многих реализациях регулярных выражений (иногда зависит от флагов). – ShuggyCoUk

+0

Не хочу ничего сопоставлять. Я проверю, как интерпретирует python «()». – grigoryvp

15

Чтобы соответствовать пустой - даже в многострочный режим - вы можете использовать \A\Z, так:

re.compile('\A\Z|\A\Z*|\A\Z+') 

Разница заключается в том, что \A и \Z являются начало и конец строки, в то время как ^ и $ этих может соответствовать началу/концу строк, поэтому $^|$^*|$^+ может потенциально соответствовать строке, содержащей символы новой строки (если флаг включен).

И не совпасть ничего (даже пустая строка), просто пытаются найти содержание до начала строки, например:

re.compile('.\A|.\A*|.\A+') 

Поскольку никакие символы не могут прийти до \ А (по определению) , это всегда будет не соответствовать.

+0

Ты выглядишь лучше, чем у меня, так как я предполагаю, что он выйдет быстрее, чем использовать конец строки. – ShuggyCoUk

+0

Питер, вы используете \ z (нижний регистр), в то время как мой карманный гид Python говорит мне, что утверждение конца строки - \ Z (верхний регистр) ?! – ThomasH

+0

ThomasH, оба они являются концами строки, но в верхнем регистре допускается завершающая новая строка, в то время как в нижнем регистре нет. –

1

Вы можете использовать
\z..
Это абсолютный конец строки, а затем два ничего

Если + или * является прикрепил на конце это все еще работает отказывается соответствовать что-нибудь

0

Или , используйте некоторое понимание списка, чтобы удалить бесполезные записи регулярного выражения и присоединиться, чтобы собрать их все вместе.Что-то вроде:

re.compile('|'.join([x for x in [regexp1, regexp2, ...] if x != None])) 

Не забудьте добавить некоторые комментарии рядом с этой строки кода, хотя :-)

23

(?!) всегда не совпадают. Это отрицательный внешний вид с нулевой шириной. Если то, что находится в круглых скобках, совпадает, то весь матч терпит неудачу. Учитывая, что в нем нет ничего, он будет терпеть несоответствие ни за что (включая ничего).

+3

Правильно, я просто собирался опубликовать это тоже. Это лучший способ, если ваш язык поддерживает взгляды. (? =) соответствует каждой строке. –

Смежные вопросы