我想知道是否有一种优雅的方式来匹配一个预编译的正则表达式与另一个?我想不是,但还是决定问。
说,我想在Puppet的node.pp中找到与特定模式相对应的所有节点。问题是,节点名称可以(通常是)定义为正则表达式本身。例如,可能需要在“生产”中找到所有节点。环境,所有按照惯例都以' p'然后是1或2 /^p[12].+$/
。换句话说,
p(1|2)proxy-[1-4].domain.lan
p1smtp-[1-2].domain.lan
p[12]what-not-[1-8].domain.lan
应匹配,而
q(1|2)proxy-[1-4].domain.lan
q(1|2)smtp-[1-2].domain.lan
q(1|2)what-not-[1-8].domain.lan
不应该。
目标字符串(如果编译为正则表达式)是更通用表达式的所有子案例。所以我想知道,如果有任何捷径?
当然,可以将节点名称与文字字符串相匹配,包括所有'正则表达式'变化 - 在这种特殊情况下不应该变硬。
答案 0 :(得分:4)
“如果你能想到它,那就有一个CPAN模块”。这就像Perl的规则34。
所以实际上有Regexp::Compare给出两个正则表达式字符串可以(有时)决定一个正则表达式是否匹配另一个正则子集。请注意,为此,我将输入正则表达式锚定在开头。如果is_less_or_equal
可以匹配$metarx
匹配的所有字符串,则$rx
将返回true。
use strict; use warnings; use 5.010;
use Regexp::Compare qw(is_less_or_equal);
my @rx = (
'p(1|2)proxy-[1-4].domain.lan',
'p1smtp-[1-2].domain.lan',
'p[12]what-not-[1-8].domain.lan',
'q(1|2)proxy-[1-4].domain.lan',
'q(1|2)smtp-[1-2].domain.lan',
'q(1|2)what-not-[1-8].domain.lan',
);
my $metarx = '^p[12]';
for my $rx (@rx) {
say "/$metarx/ ≥ /^$rx/ ?\t", is_less_or_equal("^$rx", $metarx) ? "yes" : "no";
}
输出:
/^p[12]/ ≥ /^p(1|2)proxy-[1-4].domain.lan/ ? yes
/^p[12]/ ≥ /^p1smtp-[1-2].domain.lan/ ? yes
/^p[12]/ ≥ /^p[12]what-not-[1-8].domain.lan/ ? yes
/^p[12]/ ≥ /^q(1|2)proxy-[1-4].domain.lan/ ? no
/^p[12]/ ≥ /^q(1|2)smtp-[1-2].domain.lan/ ? no
/^p[12]/ ≥ /^q(1|2)what-not-[1-8].domain.lan/ ? no
我相信这可以满足您的需求。 (注意:不要使用正则表达式对象,而只是普通的字符串 - 这个模块可能会遇到一些字符串困难)