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


178

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

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


3
您应该首先查阅Perl随附的出色文档。
SinanÜnür09年

5
您可能想看看一本书,例如Learning Perl(我合着)。这个问题没有很好的答案,因为它是非常基本的。教程将帮助您快速掌握基础知识。
brian d foy

Answers:


184

请参见perldoc perlop。使用ltgteqne,并cmp酌情进行字符串比较:

eq如果left参数在字符串上等于right参数,则Binary 返回true。

ne如果左参数沿字符串方向不等于右参数,则Binary 返回true。

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

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

ltlegegtcmp使用由当前区域指定的排序规则(排序)命令,如果一个传统的使用区域(但不是use locale ':not_characters')生效。参见perllocale。不要将它们与Unicode混合使用,而只能与旧式二进制编码混合使用。标准的Unicode :: Collat​​eUnicode :: Collat​​e :: Locale模块为解决排序规则问题提供了更强大的解决方案。


9
再多一个,ne不相等。
PJT

4
您可能要提到$ str1 =〜“ $ str2”(不是/ $ str2 /)将检查$ str2是否是$ str1的子字符串。
Daniel C. Sobral

@Daniel用于index查看一个字符串是否是另一个字符串的子字符串。
SinanÜnür09年

3
@Daniel:=〜“ $ str2”和=〜/ $ str2 /之间没有太大的实际区别(或者只是=〜$ str2);index是正确的工具,但是如果出于某些原因需要使用正则表达式,请执行=〜/ \ Q $ str2 \ E /。
2009年

1
@IliaRostovtsev !=ne不相同,因为!=ne被定义为不同。那有多难?!作为数字比较运算符,!=将其两个操作数都转换为数字perl -E 'say "equal" if not "a" != "b"'
SinanÜnür15年

137
  • 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中的布尔运算符获取的。您实际上应该只对布尔或数字运算使用返回值,在这种情况下,差异并不重要。)


8
我更喜欢这个答案。简短的简单示例通常对新手更有用,而不仅仅是普通的多页文档参考。
Zon

@Zon除外返回值eqgtlt等是不正确的......他们返回true或false。仅cmp返回特定的数值。
SinanÜnür15年

Perl 6使用相同的运算符,不同之legcmp在于它使用而不是用于一般比较的。
布拉德·吉尔伯特

17

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

智能匹配运算符根据两个项目的类型对其进行比较。有关5.10行为,请参见下表(我认为此行为在5.10.1中会稍有变化):

perldoc perlsyn“详细智能匹配”

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

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

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

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

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

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

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

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

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

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


它的变化不大:它正在发生根本性的变化。对于任何不简单的事物的智能匹配都被严重破坏了。
brian d foy

1
由于文档在此期间已更改,因此链接可能会更改。5.14.2 当前
Brad Gilbert


8

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

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

Perl的文本和数字没有不同的数据类型。它们都由类型“ scalar”表示。换句话说,如果您将字符串原样使用,则字符串就是数字。

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存在相同的问题,但是原因不同(含义不同)。
nobar

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.