195

如何在 Perl 中比较两个字符串?

我正在学习 Perl,我在 StackOverflow 上找到了这个基本问题,但没有找到好的答案,所以我想我会问。

4

7 回答 7

202

请参阅perldoc perlop。使用lt, gt, eq, ne, 和cmp酌情进行字符串比较:

eq如果左参数在字符串上等于右参数,则二进制返回 true。

ne如果左参数按字符串不等于右参数,则二进制返回 true。

Binarycmp返回 -1、0 或 1,具体取决于左参数是按字符串方式小于、等于还是大于右参数。

Binary~~在其参数之间进行智能匹配。...

lt, le, ge,gtcmp使用由当前语言环境指定的排序规则(排序)顺序,如果旧的使用语言环境(但不是use locale ':not_characters')有效。请参阅perllocale。不要将这些与 Unicode 混合,仅与旧的二进制编码混合。标准的Unicode::Collat​​eUnicode::Collat​​e::Locale模块为排序问题提供了更强大的解决方案。

于 2009-07-24T01:34:39.417 回答
146
  • cmp相比

    'a' cmp 'b' # -1
    'b' cmp 'a' #  1
    'a' cmp 'a' #  0
    
  • eq等于

    'a' eq  'b' #  0
    'b' eq  'a' #  0
    'a' eq  'a' #  1
    
  • ne不等于

    'a' ne  'b' #  1
    'b' ne  'a' #  1
    'a' ne  'a' #  0
    
  • lt少于

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
    
  • le小于或等于

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
    
  • gt比...更棒

    'a' gt  'b' #  0
    'b' gt  'a' #  1
    'a' gt  'a' #  0
    
  • ge大于或等于

    'a' ge  'b' #  0
    'b' ge  'a' #  1
    'a' ge  'a' #  1
    

有关perldoc perlop更多信息,请参阅。

(我将其简化为所有,但cmp返回一个既是空字符串,又是数字零值而不是 的0值,以及既是字符串'1'又是数值的值1。这些是相同的值总是从 Perl 中的布尔运算符获取。您实际上应该只将返回值用于布尔或数字运算,在这种情况下,差异并不重要。)

于 2009-07-24T01:47:24.893 回答
17

除了 Sinan Ünür 字符串比较运算符的全面列表之外,Perl 5.10 还添加了智能匹配运算符。

智能匹配运算符根据它们的类型比较两个项目。请参阅下表了解 5.10 的行为(我相信此行为在 5.10.1 中略有变化):

perldoc perlsyn《智能匹配详解》

智能匹配的行为取决于其参数的类型。它始终是可交换的,即$a ~~ $b行为与 相同$b ~~ $a。行为由下表确定:以任一顺序应用的第一行确定匹配行为。

  $a $b 匹配类型 隐含匹配码
  ====== ===== ===================================
  (重载胜过一切)

  代码[+] 代码[+] 引用相等 $a == $b   
  任何 Code[+] 标量子真值 $b−>($a)   

  Hash Hash 哈希键相同 [排序键 %$a]~~[排序键 %$b]
  Hash Array 哈希片存在 grep {exists $a−>{$_}} @$b
  哈希正则表达式哈希键 grep grep /$b/, 键 %$a
  散列 任何散列条目存在 $a−>{$b}

  数组数组数组是相同的[*]
  数组 正则表达式 数组 grep grep /$b/, @$a
  Array Num 数组包含数字 grep $_ == $b, @$a
  数组 任何数组都包含字符串 grep $_ eq $b, @$a

  任何 undef undefined !defined $a
  任何正则表达式模式匹配 $a =~ /$b/
  Code() Code() 结果相等 $a->() eq $b->()
  Any Code() 简单闭包真值 $b−>() # 忽略 $a
  Num numish[!] 数值相等 $a == $b   
  任何 Str 字符串相等 $a eq $b   
  任何 Num 数值相等 $a == $b   

  任何 任何字符串相等 $a eq $b   

+ - 这必须是其原型(如果存在)不是“”的代码引用
(带有“”原型的潜艇由下方的“代码()”条目处理)
* - 即每个元素与另一个元素中相同索引的元素匹配
大批。如果找到循环引用,我们会退回到引用
平等。   
!− 可以是实数,也可以是看起来像数字的字符串

当然,“匹配代码”并不代表真正的匹配代码:它只是为了解释预期的含义。与 grep 不同,智能匹配运算符将尽可能短路。

通过重载自定义匹配您可以通过重载~~运算符来更改对象的匹配方式。这胜过通常的智能匹配语义。见overload

于 2009-07-24T05:01:59.533 回答
11

这个问题的明显潜台词是:

为什么不能只==用来检查两个字符串是否相同?

Perl 对于文本和数字没有不同的数据类型。它们都由“标量”类型表示。换句话说,如果你这样使用字符串,它们就是数字。

if ( 4 == "4" ) { print "true"; } else { print "false"; }
true

if ( "4" == "4.0" ) { print "true"; } else { print "false"; }
true

print "3"+4
7

由于文本和数字没有被语言区分,我们不能简单地重载==运算符来为这两种情况做正确的事情。因此,Perl 提供eq了将值作为文本进行比较:

if ( "4" eq "4.0" ) { print "true"; } else { print "false"; }
false

if ( "4.0" eq "4.0" ) { print "true"; } else { print "false"; }
true

简而言之:

  • Perl 没有专门用于文本字符串的数据类型
  • 使用==or !=, 将两个操作数作为数字进行比较
  • 使用eqor ne, 将两个操作数作为文本进行比较

还有许多其他函数和运算符可用于比较标量值,但了解这两种形式之间的区别是重要的第一步。

于 2015-11-18T01:50:14.313 回答
10
print "Matched!\n" if ($str1 eq $str2)

Perl 有单独的字符串比较和数字比较运算符来帮助语言中的松散类型。您应该阅读perlop以了解所有不同的运算符。

于 2009-07-24T01:35:10.383 回答
1

如果您想提取两个字符串之间的差异,可以使用String::Diff

于 2013-06-19T03:27:02.277 回答
0

我来寻找一个解决方案,在 perl 中我可以比较 A > B 或 Z < AA。这里没有任何东西对我来说可靠,所以我想出了自己的解决方案。诀窍是为每个字母分配一个数字

例如

A=1
B=2
C=3 and so on

然后当比较 A > B 你得到相应的数字并在这种情况下比较它们 1 > 2

这是工作的perl代码。

# header
use warnings;
use strict;

#create a hash of letters
my %my_hash_lookup;
my $letter_counter=0;
foreach my $letters ('A'..'ZZ')
{
    #print "$letters \n";
    
    $letter_counter++;
    my $key = $letters;
    my $keyValue = $letter_counter;
    $my_hash_lookup{$key}=$keyValue;
}


my $size = keys %my_hash_lookup;
print "hash size: $size ...\n";

#get number value of string letters
        my $my_hash_value1 = $my_hash_lookup{"A"};
        my $my_hash_value2 = $my_hash_lookup{"B"};
        
        if  ( (defined $my_hash_value1) && (defined $my_hash_value2))
        {

            if ($my_hash_value1 == $my_hash_value2)
            {
                #equal
            }
            elsif ($my_hash_value1 > $my_hash_value2)
            {
                #greater than
                
            }
            elsif ($my_hash_value1 < $my_hash_value2)
            {
                #less than
            }
            
        }
于 2021-04-16T04:15:53.110 回答