Ответ 1
Вы можете использовать negative lookbehind, например:
.*(?<!\.config)$
Это соответствует всем строкам, кроме тех, которые заканчиваются на ".config"
Хорошо, так что это нечто совершенно глупое, но это то, что я просто никогда не научился делать и его хлопот.
Как указать строку, которая не содержит последовательность других символов. Например, я хочу совместить все строки, которые НЕ заканчиваются на .config
Я бы подумал, что могу просто сделать
.*[^(\.config)]$
но это не работает (почему бы и нет?)
Я знаю, что могу сделать
.*[^\.][^c][^o][^n][^f][^i][^g]$
но, пожалуйста, пожалуйста, скажите мне, что есть лучший способ
Вы можете использовать negative lookbehind, например:
.*(?<!\.config)$
Это соответствует всем строкам, кроме тех, которые заканчиваются на ".config"
В вашем вопросе есть два вопроса, так что вот несколько ответов.
Сопоставьте строки, которые не содержат определенную строку (скажем .config
):
^(?:(?!\.config).)*$\r?\n?
Сопоставьте строки, которые не заканчиваются в определенной строке:
^.*(?<!\.config)$\r?\n?
и, в качестве бонуса: сопоставить строки, которые не начинаются с определенной строки:
^(?!\.config).*$\r?\n?
(каждый раз, включая символы новой строки, если они есть.
О, и ответить, почему ваша версия не работает: [^abc]
означает "любой (1) символ, кроме a, b или c". Ваше другое решение также потерпит неудачу на test.hg
(потому что оно также заканчивается буквой g - ваше регулярное выражение смотрит на каждый символ отдельно, а не на целую строку .config
. Поэтому вам нужно lookaround, чтобы справиться с этим.
(?<!\.config)$
:)
Если вы не "grepping"... так как вы не используете результат совпадения, почему бы не искать строки, которые заканчиваются на .config и пропустить их? В Python:
import re
isConfig = re.compile('\.config$')
# List lst is given
filteredList = [f.strip() for f in lst if not isConfig.match(f.strip())]
Я подозреваю, что это будет работать быстрее, чем более сложное re.
Используя конструкцию [^]
, вы создали отрицательный класс символов, который соответствует всем символам, кроме тех, которые вы назвали. Порядок символов в совпадении кандидатов не имеет значения, так что это не сработает ни на одной строке, которая имеет любой из [(\.config)
(или [)gi.\onc(]
)
Используйте отрицательный lookahead (с регулярными выражениями perl) следующим образом: (?!\.config$)
. Это будет соответствовать всем строкам, которые не соответствуют буквальному ".config"
Как вы просили "лучшего способа": я бы попробовал "фильтр". Я думаю, что читать и понимать очень легко:
#!/usr/bin/perl
while(<>) {
next if /\.config$/; # ignore the line if it ends with ".config"
print;
}
Как вы можете видеть, я использовал пример кода perl. Но я думаю, вы поняли эту идею?
добавлен: этот подход можно было бы также использовать для объединения большего количества шаблонов фильтров, и он по-прежнему остается хорошо читаемым и понятным,
next if /\.config$/; # ignore the line if it ends with ".config"
next if /\.ini$/; # ignore the line if it ends with ".ini"
next if /\.reg$/; # ignore the line if it ends with ".reg"
# now we have filtered out all the lines we want to skip
... process only the lines we want to use ...
Я использовал Regexpal, прежде чем найти эту страницу, и придумал следующее решение, когда я хотел проверить, что строка не содержит расширение файла:
^(.(?!\.[a-zA-Z0-9]{3,}))*$
Я использовал флажок m
, чтобы я мог представить много строк и посмотреть, какие из них выполнялись или не совпадали.
чтобы найти строку, которая не содержит другого выражения "^(.(?!" +
, которое вы не хотите + "))*$"
Моя статья об использовании этого конкретного регулярного выражения