在此字符串中:
“< 0><<>><>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
我想匹配“< \ d {1,2}>”的所有实例除了我用一组额外的三角括号进行转义的那些,例如,我想匹配0,2,3,4而不是1,例如:
“< 0> << 1>> < 2> > < 3> &LT 4是氢; “
我想在一个正则表达式中执行此操作,但我能得到的最好的是:
(^ | [^ \<])\<>([^>] | $)(小于1为卤素\ d {1,2}?)
哪个匹配0,3,4而不是2,例如:
“< 0> << 1>>< 2>> < 3> < 4> “
是否有人知道如何使用单个正则表达式完成此操作?
答案 0 :(得分:5)
您还可以尝试conditionals:
(?(?<=<)(<\d{1,2}>(?!>))|(<\d{1,2}>))
答案 1 :(得分:2)
您可以查看negative look-behind zero-width assertion:
(?<!<)<\d{1,2}>
答案 2 :(得分:1)
假设使用输入集
"<0> <<1>> <2>> <3> <4><<5>"
我们希望匹配0,2,3,4和5.
问题是您需要使用零宽度前瞻和零宽度后视,但有三种情况需要匹配,'&lt;','&gt;'和'',和一个不匹配'&lt;&gt;'。此外,如果您希望能够提取已标记的表达式以便将匹配分配给数组,则需要避免标记您不需要的内容。所以我最终得到了非优雅的
use Data::Dumper;
my $a = "<0> <<1>> <2>> <3> <4><<5>";
my $brace_pair = qr/<[^<>]+>/;
my @matches = $a =~ /(?:(?<!<)$brace_pair(?!>))|(?:$brace_pair(?!>))|(?:(?<!<)$brace_pair)/g;
print Dumper(\@a);
如果你想把它塞进一个表达式 - 你可以。
答案 3 :(得分:0)
这是单个正则表达式的替代方案。将其拆分为><
边界的列表,然后排除<...>
。
#!/usr/bin/perl -lw
$s = "<0> <<1>> <2>> <3> <4>";
print join " ",
map { /(\d+)/; $1 }
grep !/^<.*>$/,
split />\s*</, $s;
答案 4 :(得分:0)
如果您正在使用支持外观而非条件的正则表达式(如Java),这是另一种方法:
(?=(<\d{1,2}>))(?!(?<=<)\1(?=>))\1
第一个先行可确保您处于标记的开头并将其捕获以供日后使用。第二个前瞻中的子表达式再次与标记匹配,但前提是它前面有<
后跟>
。使其成为否定前瞻,实现了您正在寻找的NOT(x和y)语义。最后,第二个\1
再次与标签匹配,这次是真实的(即,不在环视中)。
顺便说一句,我可以在第二个前瞻中使用>
而不是(?=>)
,但我认为这种方式更容易阅读并更好地表达我的意图。
答案 5 :(得分:0)
Perl
以下是一种快速简便的方法。use strict;
use warnings;
my $str = "<0> <<1>> <2>> <3> <4>";
my @array = grep {defined $_} $str =~ /<<\d+>>|<(\d+)>/g;
print join( ', ', @array ), "\n";