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

时间:2009-07-24 01:30:03

标签: perl string-comparison

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

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

7 个答案:

答案 0 :(得分:165)

perldoc perlop。根据需要使用ltgteqnecmp进行字符串比较:

  

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

     

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

     

二进制cmp返回-1,0或1,具体取决于左参数是否是字符串小于,等于或大于右参数。

     

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

     如果旧版使用区域设置,则

ltlegegtcmp会使用当前区域设置指定的排序规则(排序)顺序(但不是use locale ':not_characters')生效。见perllocale。不要将这些与Unicode混合,只与传统的二进制编码混合使用。标准Unicode::CollateUnicode::Collate::Locale模块为整理问题提供了更强大的解决方案。

答案 1 :(得分:129)

  • 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中的布尔运算符总是相同。你应该只使用boolean或numeric操作的返回值,在这种情况下,差异并不重要。)

答案 2 :(得分:17)

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

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

perldoc perlsyn "Smart matching in detail"

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

  $a      $b        Type of Match Implied    Matching Code
  ======  =====     =====================    =============
  (overloading trumps everything)

  Code[+] Code[+]   referential equality     $a == $b   
  Any     Code[+]   scalar sub truth         $b−>($a)   

  Hash    Hash      hash keys identical      [sort keys %$a]~~[sort keys %$b]
  Hash    Array     hash slice existence     grep {exists $a−>{$_}} @$b
  Hash    Regex     hash key grep            grep /$b/, keys %$a
  Hash    Any       hash entry existence     exists $a−>{$b}

  Array   Array     arrays are identical[*]
  Array   Regex     array grep               grep /$b/, @$a
  Array   Num       array contains number    grep $_ == $b, @$a 
  Array   Any       array contains string    grep $_ eq $b, @$a 

  Any     undef     undefined                !defined $a
  Any     Regex     pattern match            $a =~ /$b/ 
  Code()  Code()    results are equal        $a−>() eq $b−>()
  Any     Code()    simple closure truth     $b−>() # ignoring $a
  Num     numish[!] numeric equality         $a == $b   
  Any     Str       string equality          $a eq $b   
  Any     Num       numeric equality         $a == $b   

  Any     Any       string equality          $a eq $b   

+ − this must be a code reference whose prototype (if present) is not ""
(subs with a "" prototype are dealt with by the 'Code()' entry lower down) 
* − that is, each element matches the element of same index in the other
array. If a circular reference is found, we fall back to referential 
equality.   
! − either a real number, or a string that looks like a number

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

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

答案 3 :(得分:10)

print "Matched!\n" if ($str1 eq $str2)

Perl具有单独的字符串比较和数字比较运算符,以帮助松散键入语言。您应该阅读所有不同运营商的perlop

答案 4 :(得分:7)

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

  

why can't you just use == to check if two strings are the same?

Perl没有针对文本与数字的不同数据类型。它们都由"scalar"类型表示。换句话说,字符串数字if you use them as such

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没有专门用于文本字符串的数据类型
  • 使用==!=将两个操作数比较为数字
  • 使用eqne将两个操作数比较为文本

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

答案 5 :(得分:1)

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

答案 6 :(得分: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
            }
            
        }