【问题标题】:Comparing Multiple Strings In Perl在 Perl 中比较多个字符串
【发布时间】:2012-02-06 08:26:08
【问题描述】:

我的代码是这样的:

if ( $var eq "str1" || $var eq "str2" || $var eq "str3" )
{
...
}

有没有办法优化这个。 我想要类似的东西:

if ( $var eq ["str1" || "str2" || "str3"] ) {...}

【问题讨论】:

  • 如果“优化”是指“让它运行得更快”,那么第一个版本是最佳的(如果您对字符串进行排序,以便最有可能的字符串在前面)。

标签: perl


【解决方案1】:

根据字符串的内容,使用正则表达式非常方便:

if ($var =~ /^(str1|str2|str3)$/) { … }

如果做不到这一点,你可以用 grep 遍历一个列表:

if (grep { $var eq $_ } qw{str1 str2 str3}) { … }

【讨论】:

  • 非常感谢.. 第一个表达式有效,但去掉了括号:if ($var =~ /^str1|str2|str3$/)
  • @user988967,不,它没有。如果没有括号,它将匹配 str1AAstr2AAstr3
  • @ikegami,是的,你是对的。谢谢..还有一个查询。我在代码顶部使用“使用严格”。所以你会建议我使用“?:”
  • @user988967,我不明白这个问题。 use strict; 与正则表达式无关,我已经解释了为什么需要 (?:...)(...) 也可以,但它的功能是捕获,这里没必要。
  • @ikegami:我不同意那个编辑。添加?: 对程序员来说是不必要的复杂性,因此是过早优化的情况。我只使用?: 以避免与预期捕获混淆。
【解决方案2】:

在 Perl 5.10 或更高版本中:

if ($var ~~ [qw( str1 str2 str3 )]) { ...} 

~~ 运算符在其参数之间执行smart match

【讨论】:

  • @MarceloCantos:“智能匹配运算符是实验性的,它的行为可能会发生变化。”我建议你避免使用它
  • @Borodin:我通常避免使用 Perl,但无论如何都要为单挑 +1。
【解决方案3】:
  1. 使用List::MoreUtils qw{any}

    use List::MoreUtils qw{any};
    
    if ( any { $var eq $_ } 'str1', 'str2', 'str3' ) {
        ...
    }
    

    这可能比使用grep 更快,因为List::MoreUtils::any 在找到匹配项时会提前完成,而grep 可能会构建完整的匹配项列表。我说“可能”是因为 Perl 可以优化if (grep ...。可能不会。但是List::MoreUtils::any 确实提前结束了,而且它比if (grep ... 成语更具描述性。

  2. 创建一个包含所有要匹配的字符串键的哈希

    my %matcher;
    
    @matcher{qw{str1 str2 str3}} = ();
    
    if ( exists $matcher{$var} ) {
        ...
    }
    

    这有设置时间和用于哈希的内存成本的缺点,但优点是匹配时间更像 O(log N)。因此,如果您有很多不同的 $var 值要测试,那么总体上它可能会更快。

  3. 创建一个匹配所有字符串的正则表达式

    if ( $var =~ m/^str[123]$/so ) {
        ...
    }
    

    好的,如果你的字符串字面意思是qw{str1 str2 str3},这很好,但是如果它是一个任意字符串的列表呢?

    您可以使用Regexp::Assemble 将正则表达式列表融合到一个优化的正则表达式中。

【讨论】:

【解决方案4】:

对于固定字符串的列表,将您的列表转换为哈希。如果您要多次检查您的列表,并且您的列表变得更大,这将特别有用。

%on_my_list = map {; $_ => 1 } 'str1', 'str2', 'str3', ...;

if ($on_my_list{$var}) { ... }

【讨论】:

    【解决方案5】:

    我是半开玩笑的,但这样就可以了:

    use Quantum::Superpositions;
    
    if ($x == any($a, $b, $c)) { ...  }
    

    另见Perl Monks thread

    【讨论】:

      猜你喜欢
      • 2015-03-14
      • 1970-01-01
      • 2010-11-13
      • 2015-06-17
      • 2013-08-01
      • 2012-03-23
      • 1970-01-01
      • 2015-10-06
      • 2012-01-23
      相关资源
      最近更新 更多