Регулярное выражение,которое соответствует строке,не содержащей слова.

regex regex-negation


Я знаю, что можно сопоставить слово, а затем отменить совпадения, используя другие инструменты (например, grep -v ). Однако можно ли сопоставить строки, которые не содержат определенного слова, например hede , с помощью регулярного выражения?

Input:

hoho
hihi
haha
hede

Code:

grep "<Regex for 'doesn't contain hede'>" input

Желаемый выход:

hoho
hihi
haha



Answer 1 Bart Kiers


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

^((?!hede).)*$

Приведенное выше регулярное выражение будет соответствовать любой строке или строке без разрыва строки, не содержащей (под) строку 'hede'. Как уже упоминалось, это не то , что регулярное выражение «хорошо» в (или должны делать), но все же, это возможно.

И если вам нужно сопоставить и символы разрыва строки, используйте модификатор DOT-ALL (конечные s в следующем шаблоне):

/^((?!hede).)*$/s

или используйте его в строке:

/(?s)^((?!hede).)*$/

(где /.../ - разделители регулярных выражений, т. е. не являются частью шаблона)

Если модификатор DOT-ALL недоступен, вы можете имитировать то же поведение с классом символов [\s\S] :

/^((?!hede)[\s\S])*$/

Explanation

Строка - это просто список из n символов. До и после каждого символа есть пустая строка. Таким образом, список из n символов будет иметь n+1 пустых строк. Рассмотрим строку "ABhedeCD" :

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
    └──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘

index    0      1      2      3      4      5      6      7

где e - пустые строки. (?!hede). выражение (?! Hede). смотрит вперед, чтобы увидеть, нет ли подстроки "hede" , и если это так (то есть что-то еще), то . (точка) будет соответствовать любому символу, кроме разрыва строки. Осмотры также называются утверждениями нулевой ширины, потому что они не потребляют никаких символов. Они только утверждают / подтверждают что-то.

Итак, в моем примере каждая пустая строка сначала проверяется, чтобы увидеть, нет "hede" впереди «хеде» , прежде чем символ будет использован символом . (точка). (?!hede). выражение (?! Hede). будет делать это только один раз, поэтому он будет заключен в группу и повторен ноль или более раз: ((?!hede).)* . Наконец, начало и конец ввода привязываются, чтобы убедиться, что весь ввод используется: ^((?!hede).)*$

Как вы можете видеть, ввод "ABhedeCD" не удастся, потому что на e3 не выполнено регулярное выражение (?!hede) (впереди есть "hede" !).




Answer 2 FireCoding


Обратите внимание, что решение не начинается с «хеде» :

^(?!hede).*$

обычно гораздо эффективнее, чем решение , не содержащее «хеде» :

^((?!hede).)*$

Первый проверяет «hede» только в первой позиции входной строки, а не в каждой позиции.




Answer 3 Athena


Если вы просто используете его для grep, вы можете использовать grep -v hede , чтобы получить все строки, которые не содержат hede.

ЭТА О, перечитывая вопрос, grep -v - это, вероятно, то, что вы имели в виду под "настройками инструментов".




Answer 4 Jessica


Answer:

^((?!hede).)*$

Explanation:

^ начало строки, ( сгруппировать и записать в \ 1 (0 или более раз (соответствует максимально возможному количеству)),
(?! посмотрите вперед, чтобы увидеть, если нет,

hede твоя нить,

) Конца заглядывая вперёд, . любой символ кроме \ n,
)* конец \ 1 (Примечание: поскольку вы используете квантификатор для этого захвата, в \ 1 будет сохранено только последнее повторение захваченного шаблона)
$ перед необязательным \ n и концом строки




Answer 5 Hades32


Полученные ответы совершенно нормальные,просто академический балл:

Регулярные выражения в смысле теоретических компьютерных наук НЕ МОГУТ делать это так. Для них это должно было выглядеть примерно так:

^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$) 

Это только полное совпадение.Делать это для субматчей было бы еще более неудобно.