regex - 我可以从一组散列键构建 Perl 正则表达式吗

标签 regex perl hash

(与上一个问题相关: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"
);

我需要检查评论标题的格式是否正确,如果是,则链接到单独的 URL。

例如,如果评论标题是
"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 方法来做到这一点。或者有吗?

最佳答案

您的主要问题来自尝试使用 +连接字符串。它在 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是一个转义字符串中出现的任何正则表达式元字符的函数。您的示例中没有任何内容,但始终使用它并避免意外错误是一种很好的做法。

我省略了尾随 .*在你的模式中,因为如果你实际上没有对这些东西做任何事情,就没有必要说“然后是一些东西,或者可能没有东西”。该模式不需要匹配整个字符串,除非您将其 anchor 定到字符串的开头和结尾。

关于regex - 我可以从一组散列键构建 Perl 正则表达式吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22341722/

相关文章:

mysql - MySQL 中的 Bcrypt?

php - 使用基于时间的旋转散列或字符串来确保安全

python - 使用 re.finditer 和 re.match 时的不同行为

python - Lucene 或 Python : Select both "Hilary Clinton" and "Clinton, Hilary" name entries

java - 正则表达式字符串中的两个相等字符

java - 如何编写 XSD 来验证转义的 xml 数据模式

c# - 如何将复杂的二进制 Perl 正则表达式转换为 C# 或 PowerShell?

文件哈希 : Does it change for same content but in different order?

perl - 找到指向另一个哈希值的哈希值

perl - File::Basename->fileparse 返回 "File::Basename"