(与上一个问题相关:Do I need to reset a Perl hash index?)
我有一个来自文件的哈希,其定义如下:
%project_keys = (
cd => "continuous_delivery",
cm => "customer_management",
dem => "demand",
dis => "dis",
do => "devops",
sel => "selection",
seo => "seo"
);
我需要检查评论标题是否具有正确的格式,如果是,请链接到单独的网址。
例如,如果评论标题是
"cm1234 - Do some CM work"
然后我想链接到以下网址:
http://projects/customer_management/setter/1234
目前,我正在使用以下(硬编码)正则表达式:
if ($title =~ /(cd|cm|dem|dis|do|sel|seo)(\d+)\s.*/) {
my $url = 'http://projects/'.$project_keys{$1}.'/setter/'.$2
}
但显然我想从散列键本身构建正则表达式(上面的散列示例会相当频繁地更改)。我想过简单地按键连接键如下:
# Build the regex
my $regex = '';
foreach my $key ( keys %project_keys ) {
$regex += $key + '|';
}
$regex = substr($regex, 0, -1); # Chop off the last pipe
$regex = '('.$regex.')(\d+)\s.*';
if ($title =~ /$regex/) {
my $url = 'http://projects/'.$project_keys{$1}.'/setter/'.$2
}
但是a)它没有按照我的意愿工作,而b)我认为Perl的方法要好得多。或者有吗?
答案 0 :(得分:6)
您的主要问题来自于尝试使用+
来加入字符串。它在Perl中没有这样做,字符串连接运算符是.
。但是,使用join
代替字符串连接的循环通常可以做得更好。
我建议:
my $project_match = join '|', map quotemeta, keys %project_keys;
if ($title =~ /($project_match)(\d+)\s/) {
my $url = 'http://projects/'.$project_keys{$1}.'/setter/'.$2;
# Something with $url
}
quotemeta
是一个函数,可以转义字符串中出现的任何正则表达式元字符。您的示例中没有任何内容,但始终使用它并避免意外错误是一种很好的做法。
我在你的模式中遗漏了.*
,因为没有必要说"然后有些东西,或者没有东西"如果你实际上没有对这些东西做任何事情。该模式不需要匹配整个字符串,除非您将其锚定到字符串的开头和结尾。