Regex для всех строк, не содержащих строку?
Итак, это что-то совершенно глупое, но это то, что я просто никогда не учился делать, и это хлопотно.
Как мне указать строку, которая не содержит последовательность других символов. Например, я хочу сопоставить все строки, которые НЕ заканчиваются на.config
Я думаю, что я мог бы просто сделать
.*[^(\.config)]$
но это не работает (почему нет?)
Я знаю, что могу сделать
.*[^\.][^c][^o][^n][^f][^i][^g]$
но, пожалуйста, пожалуйста, скажите мне, что есть лучший способ
7 ответов
Вы можете использовать отрицательный взгляд сзади, например:
.*(?<!\.config)$
Это соответствует всем строкам, кроме тех, которые заканчиваются на ".config"
Ваш вопрос содержит два вопроса, поэтому вот несколько ответов.
Строки соответствия, которые не содержат определенную строку (скажем, .config
) совсем:
^(?:(?!\.config).)*$\r?\n?
Строки соответствия, которые не заканчиваются определенной строкой:
^.*(?<!\.config)$\r?\n?
и, в качестве бонуса: сопоставьте строки, которые не начинаются с определенной строки:
^(?!\.config).*$\r?\n?
(каждый раз, включая символы новой строки, если есть.
Да, и чтобы ответить, почему ваша версия не работает: [^abc]
означает "любой один (1) символ, кроме a, b или c". Ваше другое решение также потерпит неудачу test.hg
(потому что оно также заканчивается буквой g - ваше регулярное выражение смотрит на каждый символ отдельно, а не на весь .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())]
Я подозреваю, что это будет работать быстрее, чем более сложные.
Как вы просили "лучший путь": я бы попробовал "фильтрующий" подход. Я думаю, что это довольно легко читать и понимать:
#!/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 ...
Используя [^]
Таким образом, вы создали класс отрицанных символов, который соответствует всем символам, кроме названных вами. Порядок символов в совпадении кандидата не имеет значения, поэтому это не удастся для любой строки, которая имеет [(\.config)
(или же [)gi.\onc(]
)
Используйте отрицательный взгляд (с регулярными выражениями Perl) следующим образом: (?!\.config$)
, Это будет соответствовать всем строкам, которые не соответствуют литералу ".config"
Я использовал Regexpal до того, как нашел эту страницу, и предложил следующее решение, когда хотел проверить, что строка не содержит расширение файла:
^(.(?!\.[a-zA-Z0-9]{3,}))*$
Я использовал m
флажок, чтобы я мог представить много строк и посмотреть, какие из них соответствуют или не совпадают.
чтобы найти строку, которая не содержит другой "^(.(?!" +
Вы не хотите выражения + "))*$"
Моя статья об использовании этого конкретного регулярного выражения