使用文字小于括号的名称组

时间:2014-05-14 15:04:13

标签: regex

我有一个看起来基本上像这样的正则表达式:

<(title|head)>(.*?)(String)(.*?<\/\1>

我正在尝试使用名称组来识别部分

(?P<TITLE>(<(title|head)>))(.*?)(?P<NAME>(String))(.*?<\/\1>

当我不使用TITLE名称组时,这是有效的:

(<(title|head)>)(.*?)(?P<NAME>(String))(.*?<\/\1>

但是当我使用TITLE名称组而我没有收到错误时,我突然失去了比赛。有关如何使用&lt;&gt;?捕获正则表达式部分的任何想法我试过逃避&gt;以及:

(?P<TITLE>(\<(title|head)\>))(.*?)(?P<NAME>(String))(.*?<\/\1>

无济于事

2 个答案:

答案 0 :(得分:1)

混合命名和编号捕获组的编号

支持命名捕获的正则表达式工具(Python,.NET,PCRE / PHP,Perl 5.10等)以不同方式处理混合命名和编号捕获组的编号。 .NET风格首先从左到右对所有编号(非命名)编号,然后返回并为命名组编号。但是,PCRE / PHP风格从左到右依次计算命名和编号的捕获组。这是你的正则表达式,(固定 - 添加缺少的右括号),并在两种风格中完全注释,显示混合捕获组的编号方式:

PCRE / PHP混合捕获编号示例:

$re_php = '%
    # PCRE/PHP mixed capture numbering example.
    (?P<TITLE>          # $1: = $TITLE:
      (                 # $2:
        <(title|head)>  # $3:
      )                 # End $2:
    )                   # End $1: = $TITLE:
    (.*?)               # $4:
    (?P<NAME>           # $5: = $NAME:
      (String)          # $6:
    )                   # End $5: = $NAME:
    (.*?)               # $7:
    </\1>               # Error! Should be "\3".
    %x';

.NET Mixed捕获编号示例:

Regex re_csharp = new Regex(@"
    # .NET mixed capture numbering example.
    (?<TITLE>           # $TITLE: = $6:
      (                 # $1:
        <(title|head)>  # $2:
      )                 # End $1:
    )                   # End $TITLE: = $6:
    (.*?)               # $3:
    (?<NAME>            # $NAME: = $7:
      (String)          # $4:
    )                   # End $NAME: = $7:
    (.*?)               # $5:
    </\1>               # Error! Should be '\2'.
    ", RegexOptions.IgnorePatternWhitespace);

正如蒂姆所说,你的正则表达式还存在其他问题,但我不会在这里解决它们。

底线:

最好不要混合两种类型的捕获组。使用所有已命名或所有编号的捕获组。你的生活会更好!

那就是说,我强烈建议阅读:Mastering Regular Expressions (3rd Edition)这是我收集上述信息的地方。 (请放下,我读过的最有用的书。)

快乐的复兴!

答案 1 :(得分:0)

如果从命名的捕获组中删除该名称,它将成为编号的捕获组(从左到右编号)。

这意味着\1将不再反向引用群组(title|head),而是群组(<(title|head)>),当然会失败。

如果你将反向引用改为\2,它应该再次起作用(尽管你的正则表达式在语法上是无效的,至少缺少一个右括号,所以我无法测试它。)