Регулярное выражение для исключения слова / строки

299

У меня есть регулярное выражение следующим образом:

^/[a-z0-9]+$

Это соответствует строки, такие как /helloили /hello123.

Однако я хотел бы исключить пару строковых значений, таких как /ignoremeи /ignoreme2.

Я перепробовал несколько вариантов, но не могу заставить их работать!

Моя последняя слабая попытка была

^/(((?!ignoreme)|(?!ignoreme2))[a-z0-9])+$

Любая помощь будет с благодарностью :-)

romiem
источник
1
Возможный дубликат: stackoverflow.com/questions/1395177/…
Андерсон Грин

Ответы:

376

Вот еще один способ (использование негативного прогнозирования ):

^/(?!ignoreme|ignoreme2|ignoremeN)([a-z0-9]+)$ 

Примечание: Там только одно выражение захвата: ([a-z0-9]+).

Сет
источник
1
Блестящий, похоже, сделал свое дело. Мне действительно нужно это правило для перезаписи URL, и я хотел игнорировать папки "images", "css" и "js". Поэтому мое правило таково: ^ / (?! css | js | images) ([az] +) /? (\? (. +))? $, И оно переписывается в /Profile.aspx?id=$1&$3 Будет ли это правило работать правильно и распространять строку запроса тоже? Поэтому, если кто-то посещает mydomain.com/hello?abc=123, я бы хотел, чтобы он переписал mydomain.com/Profile.aspx?id=hello&abc=123. Я также немного не уверен в производительности (. +) В конец для захвата строки запроса в исходном запросе.
Ромием
Похоже, это другой вопрос. Ваше регулярное выражение выглядит так, как будто оно захватит строку запроса - проверьте и посмотрите, подходит ли ваша строка запроса. Также - (\?(.+))?$должно быть быстро. Я бы не слишком беспокоился о скорости.
Сет
1
У меня это не сработало, а решение Аликс Аксель сработало. Я использую java.util.regex.Patternкласс Java .
Марк Жеронимус
1
Я подтверждаю reMark Марка;) - например, Pycharm основан на Java, не так ли? Таким образом, учитывая регулярные выражения в поиске Пихарма, решение Аликс работает, другое - нет.
Фанни
43

Это должно сделать это:

^/\b([a-z0-9]+)\b(?<!ignoreme|ignoreme2|ignoreme3)

Вы можете добавить столько игнорируемых слов, сколько захотите, вот простая реализация PHP:

$ignoredWords = array('ignoreme', 'ignoreme2', 'ignoreme...');

preg_match('~^/\b([a-z0-9]+)\b(?<!' . implode('|', array_map('preg_quote', $ignoredWords)) . ')~i', $string);
Аликс Аксель
источник
я думал, что оглядывание требует шаблон фиксированной ширины?
Симон
2
@AlixAxel Это так, но более умные библиотеки регулярных выражений позволят чередовать альтернативы различной длины (и использовать самую длинную), если каждая альтернатива имеет фиксированную длину.
ChrisF
это умно, но для меня не получается, если игнорируемое слово находится в конце любого другого слова. то есть, если вы добавите «a» как одно из пропущенных слов, то любое слово, оканчивающееся на a, будет проигнорировано
singmotor
21

Поскольку вы хотите исключить оба слова, вам нужна комбинация:

^/(?!ignoreme$)(?!ignoreme2$)[a-z0-9]+$

Теперь оба условия должны быть истинными (ни ignoreme, ни ignoreme2 не разрешены) для совпадения.

гумбо
источник
1
Это эквивалентно более короткому описанному выше, который является негативным взглядом на множество альтернатив.
ChrisF
4
@ ChrisFF Нет, не совсем. Решение Сет не будет соответствовать что - то вроде /ignoremenotкак /следует ignoreme.
Гамбо