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 строка. Вот почему вам нужен обходной путь, чтобы справиться с этим.

(?<!\.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 флажок, чтобы я мог представить много строк и посмотреть, какие из них соответствуют или не совпадают.

чтобы найти строку, которая не содержит другой "^(.(?!" + Вы не хотите выражения + "))*$"

Моя статья об использовании этого конкретного регулярного выражения

Другие вопросы по тегам