Обнаружение отсутствия слов в регулярном выражении - PullRequest
1 голос
/ 10 апреля 2011

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

У меня есть строкикода, подобного этому:

Пример первый:

protected static readonly string BACKGROUND_MUSIC_NAME = "Music_Mission_Complete_Loop_audio";

А вот еще один:

mainWindow.Id = "MainWindow";

Окончательный вариант:

mainStoLabel.Text = "#stb_entry_clah";

Iхотите захватить только среднюю, обнаружив, что все строки, подобные этим, что а.) не предшествуют "#" в фактической строке между кавычками, а б.) вообще не предшествуют слову "только для чтения".

Мое текущее регулярное выражение таково:

.*\W\=\W"[^#].*"

В нем представлены два верхних примера.Теперь я просто хочу сузить верхний пример.Как мне зафиксировать отсутствие (не символов) целых слов.

Спасибо.

Ответы [ 4 ]

2 голосов
/ 11 апреля 2011

Ошибка в вашем прогнозном утверждении об отрицании состоит в том, что вы не собрали все вместе в соответствии с общим случаем.Вы должны сделать так, чтобы его утверждение применялось к каждой позиции персонажа, когда вы ползете вперед.Это относится только к одной возможной точке так, как вы ее написали, в то время как она нужна для применения ко всем из них.Ниже описано, как вы должны сделать это, чтобы сделать это правильно.

Вот рабочая демонстрация, которая показывает два разных подхода:

  1. Первый использует отрицательный прогноз, чтобы гарантироватьчто левая часть не содержит только для чтения , а правая часть не начинается со знака числа.

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

Демонстрационный язык - Perl, но одни и те же шаблоны и логика должны работать практически везде.

#!/usr/bin/perl

while (<DATA>) {
    chomp;
#
# First demo: use a complicated regex to get desired part only
#
    my($label) = m{
        ^                           # start at the beginning
        (?:                         # noncapture group:
            (?! \b readonly \b )    #   no "readonly" here
            .                       #   now advance one character
        ) +                         # repeated 1 or more times
        \s* = \s*                   # skip an equals sign w/optional spaces
        " ( [^#"] [^"]* ) "         # capture #1: quote-delimited text
                                    #   BUT whose first char isn't a "#"
    }x;

    if (defined $label) {
        print "Demo One: found label <$label> at line $.\n";
    }
#
# Second demo: This time use simpler patterns, several
#
    my($lhs, $rhs) = m{
        ^                       # from the start of line
        ( [^=]+ )               # capture #1: 1 or more non-equals chars
        \s* = \s*               # skip an equals sign w/optional spaces
        " ( [^"]+ ) "           # capture #2: all quote-delimited text
    }x;

    unless ($lhs =~ /\b readonly \b/x || $rhs =~ /^#/) {
        print "Demo Two: found label <$rhs> at line $.\n";
    }

}
__END__
protected static readonly string BACKGROUND_MUSIC_NAME = "Music_Mission_Complete_Loop_audio";
mainWindow.Id = "MainWindow";
mainStoLabel.Text = "#stb_entry_clah";

У меня есть два совета.Во-первых, убедитесь, что вы ВСЕГДА используете режим /x, чтобы вы могли создавать документированные и поддерживаемые регулярные выражения.Во-вторых, гораздо чище делать что-то по очереди, как во втором решении, а не все сразу, как в первом.

2 голосов
/ 10 апреля 2011

Я не совсем понимаю ваш вопрос, негативный взгляд будет выглядеть так:

(?!.*readonly)(?:.*\s\=\s"[^#].*")

Первая часть будет соответствовать, если в строке нет слова «только для чтения».

Какой язык вы используете?

Что вы хотите сопоставить, только второй пример, я правильно понял?

1 голос
/ 10 апреля 2011

^[^"=]*(?<!(^|\s)readonly\s.*)\s*=\s*"[^#].*", кажется, соответствует вашим потребностям:

  • все до первого знака равенства не должно содержать readonly или кавычек
  • readonly распознается без границ словано с пробелами (кроме начала строки)
  • знак равенства может быть окружен произвольным пробелом
  • за знаком равенства должна следовать строка в кавычках
  • строка в кавычкахне должен начинаться с #

Вы можете работать с обходными группами или группами захвата, если вы хотите только строки или строки в кавычках.

Примечание: согласно вашему собственному регулярному выражению это отбрасываетчто-нибудь после последней цитаты (не совпадающей с точкой с запятой в ваших примерах)

0 голосов
/ 10 апреля 2011

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

Посмотрите на этом сайте, как сделать это в Delphi, GNU (Linux), Groovy, Java, JavaScript, .NET, PCRE (C / C ++), Perl, PHP, POSIX, PowerShell, Python, R, REALbasic, Ruby, Tcl, VBScript, Visual Basic 6, wxWidgets, XML-схема, XQuery & XPath

...