Regex для строки, не заканчивающейся с заданным суффиксом

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

Соответствует

b
ab
1

Это не соответствует

a
ba

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

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

Я смог исправить это, используя этот поток:

.*(?:(?!ab).).$

Хотя недостатком этого является то, что он не соответствует строке одного символа.

Ответ 1

Вы не даете нам язык, но если ваш regex-аромат поддерживает смотреть за утверждением, это то, что вам нужно:

.*(?<!a)$

(?<!a) является отрицательным утверждением lookbehind, которое гарантирует, что до конца строки (или строки с модификатором m) не существует символа "a".

Смотрите здесь, в Regexr

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

.*(?<!ab)$

Это будет соответствовать тому, что не заканчивается словами "ab", см. в Regexr

Ответ 2

Используйте символ не (^):

.*[^a]$

Если вы положите символ ^ в начале скобок, это означает "все, кроме вещей в скобках". $ является просто привязкой к концу.

Для нескольких символов просто поместите их в свой собственный набор символов:

.*[^a][^b]$

Ответ 3

Для поиска файлов, не заканчивающихся на ".tmp", мы используем следующее регулярное выражение:

^(?!.*[.]tmp$).*$

Протестировано с помощью Regex Tester дает следующий результат:

введите описание изображения здесь

Ответ 4

.*[^a]$

приведенное выше выражение будет соответствовать строкам, которые не заканчиваются на a.

Ответ 5

Попробуйте это

/.*[^a]$/

[] обозначает класс символов, а ^ инвертирует класс символов для соответствия всем, кроме a.

Ответ 6

Все, что соответствует чему-то, что заканчивается на --- .*a$ Итак, когда вы сопоставляете регулярное выражение, отрицайте условие или в качестве альтернативы вы также можете сделать .*[^a]$, где [^a] означает все, что есть not a

Ответ 7

Вопрос старый, но я не мог найти лучшего решения, которое я размещаю здесь. Найти все USB-накопители, но не перечислять разделы, тем самым удалив "часть [0-9]" из результатов. Я закончил делать два grep, последний отрицает результат:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

Это приводит к моей системе:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Если мне нужны только разделы, которые я мог бы сделать:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

Где я получаю:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

И когда я делаю:

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Я получаю:

/dev/sdb

Ответ 8

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

Если мы рассмотрим широко предложенное регулярное выражение для этого вопроса:

.*[^a]$

Мы обнаружим, что он почти работает. Он не принимает пустую строку, которая может быть немного неудобной. Однако это небольшая проблема при работе с одним персонажем. Однако, если мы хотим исключить целую строку, например. "abc", затем:

.*[^a][^b][^c]$

не будет. Например, он не принимает ac.

Однако для решения этой проблемы существует простое решение. Мы можем просто сказать:

.{,2}$|.*[^a][^b][^c]$

или более обобщенная версия:

.{,n-1}$|.*[^firstchar][^secondchar]$ где n - длина строки, которую вы хотите запретить (для abc it 3), а firstchar, secondchar,... являются первыми, вторыми... n-ыми символами вашей строки (для abc это be a, то b, тогда c).

Это происходит из простого наблюдения, что строка, которая короче, чем текст, который мы не запретим, не может содержать этот текст по определению. Таким образом, мы можем либо принять все, что короче ( "ab" не "abc" ), или что-то достаточно длинное для нас, чтобы принять, но без окончания.

Вот пример поиска, который удалит все файлы, которые не являются .jpg:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete