我需要将多个正则表达式组合成一个,所以代码看起来像这样:
my $s = "jump 0xbdf3487";
#my $s = "move 0xbdf3487";
if ($s =~ m/^(move) ([^ ]+)/) { print "matched '$1' '$2'\n"; }
if ($s =~ m/^(jump) ([^ ]+)/) { print "matched '$1' '$2'\n"; }
if ($s =~ m/^(call) ([^ ]+)/) { print "matched '$1' '$2'\n"; }
变为:
my $s = "jump 0xbdf3487";
#my $s = "move 0xbdf3487";
my @patterns = (
'^(move) ([^ ]+)',
'^(jump) ([^ ]+)',
'^(call) ([^ ]+)'
);
my $re = "(?:" . join("|", @patterns) . ")";
$re = qr/$re/;
if ($s =~ m/$re/) { print "matched '$1' '$2'\n"; }
但是,如果$s
是我们获得的跳转,那么这不起作用:
matched '' ''
组合正则表达式中的匹配重新编号:
(1美元,2美元)在跳跃正则表达式($ 5,$ 6)中变成(3美元,4美元),等等。
如何在不重新编号的情况下组合这些?
答案 0 :(得分:6)
使用分支重置模式(?|pattern)
(您需要Perl 5.10或更新版本)。引用文档(perldoc perlre
):
这是“分支重置”模式,它具有捕获组从每个交替分支中的相同起点编号的特殊属性。
您的代码变为:
use strict;
use warnings;
my $s = "jump 0xbdf3487";
#my $s = "move 0xbdf3487";
my @patterns = (
'(move) ([^ ]+)',
'(jump) ([^ ]+)',
'(call) ([^ ]+)'
);
my $re = "^(?|" . join("|", @patterns) . ")";
$re = qr/$re/;
if ($s =~ m/$re/) { print "matched '$1' '$2'\n"; }
请注意,我已添加use strict
和use warnings
,请勿忘记!
答案 1 :(得分:4)
您可以在正则表达式中使用简单的替换,只使用一个正则表达式:
m/^(move|jump|call) ([^ ]+)/
<强>代码:强>
my $s = "jump 0xbdf3487";
if ($s =~ m/^(move|jump|call) ([^ ]+)/) {
print "matched '$1' '$2'\n";
}
答案 2 :(得分:1)
Perl Regex子模式可以通过管道连接在一起,使它们交替出现模式。要将交替模式与表达模式的其余部分分开,请将它们分组为一个组。如果您不想捕获该组匹配的内容,请将其设为非捕获组。
例如,在模式中的捕获组中进行更改:
(move|jump|call) ([^ ]+)
在模式中的非捕获组中进行交替:
(?:move|jump|call) ([^ ]+)
如果您的替代模式很复杂,并且您不希望它们全部在一行上,则可以使用/ x修饰符将它们与空格分开。
Perldoc PerlRe Modifiers(向下滚动到“某些修饰符的详细信息”)
/ X
/ x告诉正则表达式解析器忽略大多数空格 既不是倒退也不是在括号内的角色类中。您可以 用这个来将你的正则表达式分解成(略微)更多 可读部分。此外,“#”字符被视为元字符 引入一个满足模式结束分隔符的注释, 如果图案延伸到下一个图案,则到当前行的末尾 线。因此,这非常像普通的Perl代码注释。 (只有在您的情况下,您才可以在注释中包含结束分隔符 在它前面加一个反斜杠,所以要小心!)
使用/ x表示如果你想要真正的空格或“#”字符 模式(在括号内的字符类之外,不受影响 通过/ x),那么你要么必须逃避它们(使用反斜杠或 \ Q ... \ E)或使用八进制,十六进制或\ N {}转义对它们进行编码。它是 尝试继续评论到下一行是无效的 使用反斜杠或\ Q。
转义\ n
这是我的例子,证明:
#!/usr/bin/perl
use strict;
use warnings;
my $s = "jump 0xbdf3487";
if ($s =~ /^(
move # first complicated pattern
|
jump # second complicated pattern
|
call # third complicated pattern
)\s([^\ ]+) /x) { # Note I hade to escape the space
# with a backslash because of /x
print "matched '$1' '$2'\n";
}
哪个输出:
matched 'jump' '0xbdf3487'