Как вложенные группы фиксации пронумерованы в регулярных выражениях?

Управление файлом обычно не делается Bash, но программами, вызванными Bash, например:

perl -pi -e 's/abc/XYZ/g' /tmp/file.txt

Эти -i флаг говорит этому делать оперативную замену.

Видят man perlrun для получения дополнительной информации, включая то, как взять резервное копирование исходного файла.

75
задан Alan Storm 22 August 2009 в 18:54
поделиться

4 ответа

Из perlrequick

Если группировки в регулярном выражении вложенный, $ 1 получает группу с крайняя левая открывающая скобка, $ 2 - следующая открывающая скобка и т. д.

Предостережение : исключение открывающей скобки для группы, не связанной с захватом (? =)

Обновление

Я не часто использую PCRE, поскольку обычно использую настоящие;), но документы PCRE показывают то же, что и Perl:

ПОДРАЗДЕЛЕНИЯ

2. Он устанавливает подшаблон как захватывающий подшаблон. Это означает, что при совпадении всего шаблона та часть строки темы, которая соответствует подшаблону, возвращается вызывающей стороне через аргумент ovector pcre_exec () . Открывающие круглые скобки подсчитываются слева направо (начиная с 1), чтобы получить номер для фиксируемых подшаблонов.

Например, если строка «красный король» совпадает с шаблоном

, ((красный | белый) (король | королева))

захваченные подстроки - это «красный король», «красный» и «король», и они пронумерованы соответственно 1, 2 и 3.

Если PCRE отходит от совместимости с регулярными выражениями Perl, возможно, следует использовать аббревиатуру. быть переопределенным - "Perl Cognate Regular Expressions", "Perl Comparable Regular Expressions" или что-то в этом роде. Или просто избавьтесь от смысловых букв.

56
ответ дан 24 November 2019 в 11:43
поделиться
\ 0 или $ 0 относятся к тексту, соответствующему всему шаблону. Открывающие скобки отсчитываются слева направо (начиная с 1), чтобы получить номер подшаблона захвата. "(Это также верно для устаревших функций POSIX)
  • PCRE - http: // www .pcre.org / pcre.txt
    Чтобы добавить к тому, что сказал Алан М, найдите «Как pcre_exec () возвращает захваченные подстроки» и прочтите пятый абзац, который следует ниже:

     Первая пара целых чисел, ovector [0 ] и овектор [1], определите
    часть строки темы, соответствующая всему шаблону. Следующий
    пара используется для первого подшаблона захвата и так далее. Значение
    возвращается pcre_exec (), это на единицу больше, чем пара с самым большим номером,
    был установлен. Например, если были захвачены две подстроки,
    возвращаемое значение - 3. Если нет захватывающих подшаблонов, возврат
    значение успешного совпадения равно 1, что указывает на то, что только первая пара
    офсетов.
    
  • Различные Perl - http://perldoc.perl.org/perlre.html#Capture-buffers
    $ 1, $ 2 и т. Д. Соответствуют группам захвата, как и следовало ожидать (т. Е. По появлению открывающая скобка), однако $ 0 возвращает имя программы, а не всю строку запроса - чтобы получить это, вместо этого вы используете $ &.
  • Вы, скорее всего, найдете аналогичные результаты для других языков (Python, Ruby и др.).

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

    Помещение всей строки совпадения в позицию 0 также имеет смысл - в основном для согласованности. Это позволяет всей согласованной строке оставаться в том же индексе независимо от числа групп захвата от регулярного выражения до регулярного выражения и независимо от количества групп захвата, которые фактически соответствуют чему-либо (например, Java будет свертывать длину массива согласованных групп для каждого захвата group не соответствует какому-либо контенту (подумайте, например, о чем-то вроде «шаблон (. *)»). Вы всегда можете проверить capturing_group_results [capturing_group_results_length - 2], но это плохо переводится на языки Perl, которые динамически создают переменные ($ 1 , $ 2 и т. Д.) (Perl, конечно, плохой пример, поскольку он использует $ & для совпадающего выражения, но вы поняли идею :).

    Помещение всей строки соответствия в позицию 0 также имеет смысл - в основном для согласованности. Это позволяет всей согласованной строке оставаться в том же индексе независимо от числа групп захвата от регулярного выражения до регулярного выражения и независимо от количества групп захвата, которые фактически соответствуют чему-либо (например, Java будет свертывать длину массива согласованных групп для каждого захвата group не соответствует какому-либо контенту (подумайте, например, о чем-то вроде «шаблон (. *)»). Вы всегда можете проверить capturing_group_results [capturing_group_results_length - 2], но это плохо переводится на языки Perl, которые динамически создают переменные ($ 1 , $ 2 и т. Д.) (Perl, конечно, плохой пример, поскольку он использует $ & для совпадающего выражения, но вы поняли идею :).

    Помещение всей строки соответствия в позицию 0 также имеет смысл - в основном для согласованности. Это позволяет всей согласованной строке оставаться в том же индексе независимо от числа групп захвата от регулярного выражения до регулярного выражения и независимо от количества групп захвата, которые фактически соответствуют чему-либо (например, Java будет свертывать длину массива согласованных групп для каждого захвата group не соответствует какому-либо контенту (подумайте, например, о чем-то вроде "шаблона (. *)"). Вы всегда можете проверить capturing_group_results [capturing_group_results_length - 2], но это плохо переводится на языки Perl, которые динамически создают переменные ($ 1 , $ 2 и т. Д.) (Perl, конечно, плохой пример, поскольку он использует $ & для совпадающего выражения, но вы поняли идею :).

    16
    ответ дан 24 November 2019 в 11:43
    поделиться

    Порядок захвата в порядке левого парена является стандартным для всех платформ, на которых я работал. (Perl, php, ruby, egrep)

    4
    ответ дан 24 November 2019 в 11:43
    поделиться

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

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

    Regex.Replace(@"one two three four", 
                  @"(?<one>\w+) (\w+) (?<three>\w+) (\w+)",
                  @"$1 $2 $3 $4")
    
    // result: "two four one three"
    

    Фактически, номер является псевдонимом для имени ; номера, присвоенные именованным группам, начинаются там, где заканчиваются «настоящие» пронумерованные группы. Это может показаться странной политикой, но для этого есть веская причина: in. NET, вы можете использовать одно и то же имя группы более одного раза в регулярном выражении. Это делает возможным использование регулярных выражений, подобных этого потока , для сопоставления чисел с плавающей запятой из разных локалей:

    ^[+-]?[0-9]{1,3}
    (?:
        (?:(?<thousand>\,)[0-9]{3})*
        (?:(?<decimal>\.)[0-9]{2})?
    |
        (?:(?<thousand>\.)[0-9]{3})*
        (?:(?<decimal>\,)[0-9]{2})?
    |
        [0-9]*
        (?:(?<decimal>[\.\,])[0-9]{2})?
    )$
    

    Если есть разделитель тысяч, он будет сохранен в группе «тысяча» независимо от того, какая часть регулярное выражение соответствует ему. Точно так же десятичный разделитель (если он есть) всегда будет сохранен в группе «десятичный». Конечно, есть способы идентифицировать и извлекать разделители без многоразовых именованных групп, но этот способ намного удобнее, я думаю, что он более чем оправдывает странную схему нумерации.

    И еще есть Perl 5.10+, который дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    Это делает возможным использование регулярных выражений, подобных этого потока , для сопоставления чисел с плавающей запятой из разных локалей:

    ^[+-]?[0-9]{1,3}
    (?:
        (?:(?<thousand>\,)[0-9]{3})*
        (?:(?<decimal>\.)[0-9]{2})?
    |
        (?:(?<thousand>\.)[0-9]{3})*
        (?:(?<decimal>\,)[0-9]{2})?
    |
        [0-9]*
        (?:(?<decimal>[\.\,])[0-9]{2})?
    )$
    

    Если есть разделитель тысяч, он будет сохранен в группе «тысяча» независимо от того, какая часть регулярное выражение соответствует ему. Точно так же десятичный разделитель (если он есть) всегда будет сохранен в группе «десятичный». Конечно, есть способы идентифицировать и извлекать разделители без многоразовых именованных групп, но этот способ намного удобнее, я думаю, он более чем оправдывает странную схему нумерации.

    И еще есть Perl 5.10+, который дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    Это делает возможным использование регулярных выражений, подобных этого потока , для сопоставления чисел с плавающей запятой из разных локалей:

    ^[+-]?[0-9]{1,3}
    (?:
        (?:(?<thousand>\,)[0-9]{3})*
        (?:(?<decimal>\.)[0-9]{2})?
    |
        (?:(?<thousand>\.)[0-9]{3})*
        (?:(?<decimal>\,)[0-9]{2})?
    |
        [0-9]*
        (?:(?<decimal>[\.\,])[0-9]{2})?
    )$
    

    Если есть разделитель тысяч, он будет сохранен в группе «тысяча» независимо от того, какая часть регулярное выражение соответствует ему. Точно так же десятичный разделитель (если он есть) всегда будет сохранен в группе «десятичный». Конечно, есть способы идентифицировать и извлекать разделители без многоразовых именованных групп, но этот способ намного удобнее, я думаю, он более чем оправдывает странную схему нумерации.

    И еще есть Perl 5.10+, который дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    независимо от того, какая часть регулярного выражения соответствует ему. Точно так же десятичный разделитель (если он есть) всегда будет сохранен в группе «десятичный». Конечно, есть способы идентифицировать и извлекать разделители без многоразовых именованных групп, но этот способ намного удобнее, я думаю, он более чем оправдывает странную схему нумерации.

    И еще есть Perl 5.10+, который дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    независимо от того, какая часть регулярного выражения соответствует ему. Точно так же десятичный разделитель (если он есть) всегда будет сохранен в группе «десятичный». Конечно, есть способы идентифицировать и извлекать разделители без многоразовых именованных групп, но этот способ намного удобнее, я думаю, он более чем оправдывает странную схему нумерации.

    И еще есть Perl 5.10+, который дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    что дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    что дает нам больше контроля над группами захвата, чем я знаю, что с ними делать. : D

    9
    ответ дан 24 November 2019 в 11:43
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: