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

Posted

技术标签:

【中文标题】如何在 Perl 中比较两个字符串?【英文标题】:How do I compare two strings in Perl? 【发布时间】:2010-11-13 14:34:57 【问题描述】:

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

【问题讨论】:

您应该首先查阅 Perl 附带的优秀文档。 您可能想查看一本书,例如Learning Perl(我与人合着)。这个问题没有很好的答案,因为它非常基础。教程将帮助您快速掌握基础知识。 【参考方案1】:

见perldoc perlop。适当地使用ltgteqnecmp进行字符串比较:

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

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

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

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

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

【讨论】:

再多一个,ne 表示不相等。 你可能要提到 $str1 =~ "$str2" (not /$str2/) 将检查 $str2 是否是 $str1 的子字符串。 @Daniel 使用index 来查看一个字符串是否是另一个字符串的子字符串。 @Daniel: =~"$str2" 和 =~/$str2/ 之间没有太大的实际区别(或者只是 =~$str2 ); index 是正确的工具,但如果您出于某种原因需要使用正则表达式,请执行 =~/\Q$str2\E/。 @IliaRostovtsev !=ne 不一样,因为 !=ne 被定义为不同的。这有多难?!作为数字比较运算符,!= 将其两个操作数都转换为数字perl -E 'say "equal" if not "a" != "b"'【参考方案2】:

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 中的布尔运算符中始终得到的值相同。您实际上应该只将返回值用于布尔或数值运算,在这种情况下,差异并不重要。)

【讨论】:

我更喜欢这个答案。简短的简单示例通常对新手更有帮助,而不仅仅是平庸的多页文档参考。 @Zon 除了eqgtlt 等的返回值不正确......它们返回 true 或 false。只有 cmp 返回特定的数值。 Perl 6 使用相同的运算符,只是它使用leg 而不是cmp,后者用于泛型比较。【参考方案3】:

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

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

perldoc perlsyn "Smart matching in detail":

智能匹配的行为取决于其参数的类型。它始终是可交换的,即 $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

【讨论】:

它并没有轻微改变:它正在彻底改变。任何不简单的东西的智能匹配都被严重破坏了。 链接应该会改变,因为文档同时发生了变化。 5.14.2current【参考方案4】:

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

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,将两个操作数作为文本进行比较

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

【讨论】:

Java 有同样的问题,但出于不同的原因(并且具有不同的含义)。【参考方案5】:
print "Matched!\n" if ($str1 eq $str2)

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

【讨论】:

【参考方案6】:

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

【讨论】:

如果您要链接到 Perl 文档,通常建议使用永久链接,它将始终链接到模块的最新版本。 search.cpan.org/perldoc/String::Diffsearch.cpan.org/perldoc?String::Diffp3rl.org/String::Diffmetacpan.org/module/String::Diffmetacpan.org/pod/String::Diff完成【参考方案7】:

我来寻找一个解决方案,在 perl 中我可以比较 A > B 或 Z

例如

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
            
            
        

【讨论】:

以上是关于如何在 Perl 中比较两个字符串?的主要内容,如果未能解决你的问题,请参考以下文章

文本文件中的 Perl 字符串比较

perl 6集合操作中用户定义的比较函数

shell如何比较 两个字符串是不是相等?

在Perl中减去两个日期字符串,转换为unix时间并还原

如何在perl中的foreach循环中的字符串中查找和删除重复值的出现

Perl - 如何从文本文件中省略行?