我有一个看起来基本上像这样的正则表达式:
<(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>
无济于事
答案 0 :(得分:1)
支持命名捕获的正则表达式工具(Python,.NET,PCRE / PHP,Perl 5.10等)以不同方式处理混合命名和编号捕获组的编号。 .NET风格首先从左到右对所有编号(非命名)编号,然后返回并为命名组编号。但是,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';
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
,它应该再次起作用(尽管你的正则表达式在语法上是无效的,至少缺少一个右括号,所以我无法测试它。)