如何比较Perl中的两个string?

如何比较Perl中的两个string?

我正在学习Perl,我有这个基本的问题在StackOverflow查找它,发现没有好的答案,所以我想我会问。

见perldoc perlop 。 使用ltgteqnecmp作为string比较的适当值:

如果左边的参数是string等于正确的参数,则二进制eq返回true。

如果左边的参数是stringwise不等于正确的参数,二进制ne返回true。

二进制cmp根据左边的参数是否小于,等于或大于正确的参数返回-1,0或1。

二进制~~在它的参数之间做一个智能匹配。 …

如果传统使用语言环境(但不use locale ':not_characters' )有效,则使用当前语言环境指定的sorting规则(sorting)顺序, legegtcmp 。 请参阅perllocale 。 不要将这些与Unicode混合在一起,只能使用传统的二进制编码。 标准的Unicode :: Collat​​e和Unicode :: Collat​​e :: Locale模块为整理问题提供了更强大的解决scheme。

  • cmp比较

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

     '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 
  • 小于

     '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所有内容都返回一个既是空string也是数值零而不是0的值,以及既是string'1'也是数值1值。和Perl中的布尔操作符一样,你应该只使用布尔值或数值操作的返回值,在这种情况下,差异并不重要。

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

智能匹配运算符根据其types比较两个项目。 5.10行为见下图(我相信这个行为在5.10.1中略有变化):

perldoc perlsyn “智能匹配详细” :

智能匹配的行为取决于它的参数是什么types的东西。 它总是可交换的,即$a ~~ $b行为与$b ~~ $a 。 行为由下表确定:应用的第一行以任一顺序确定匹配行为。

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

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

  哈希散列哈希键相同[sorting键%$ a] ~~ [sorting键%$ b]
  哈希数组散列片存在grep {exists $ a  - > {$ _}} @ $ b
  哈希正则expression式哈希键grep grep / $ b /,键%$ a
  散列存在任何散列条目存在$ a  - > {$ b}

  数组数组是相同的[*]
   Array正则expression式arraysgrep grep / $ b /,@ $ a
   Array Num数组包含数字grep $ _ == $ b,@ $ a 
  数组任何数组包含stringgrep $ _ eq $ b,@ $ a 

  任何undef undefined!定义$ a
  任何正则expression式匹配$ a =〜/ $ b / 
   Code()Code()结果是等于$ a  - >()eq $ b  - >()
  任何Code()简单的closures事实$ b  - >()#忽略$ a
   num numish [!]数字相等$ a == $ b   
  任何Strstring相等$ a eq $ b   
  任何数字相等性$ a == $ b   

  任何任何string相等$ a eq $ b   

 +  - 这必须是一个代码引用,其原型(如果存在)不是“”
 (带有“”原型的subs由下面的Code()条目处理) 
 *  - 即每个元素都与另一个元素中的相同索引匹配
arrays。 如果find循环引用,我们回到参考 
平等。   
 !  - 一个实数,或者一个看起来像一个数字的string

当然,“匹配代码”并不代表真正的匹配代码,只是在那里解释意图的含义。 与grep不同的是,智能匹配运算符会在任何时候都会短路。

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

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

Perl有单独的string比较和数字比较运算符来帮助松散的input语言。 你应该阅读perlop所有不同的运营商。

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

为什么不能用==来检查两个string是否相同?

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

 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没有专门用于文本string的数据types
  • 使用==!= ,将两个操作数作为数字进行比较
  • 使用eqne ,将两个操作数作为文本进行比较

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

如果你想提取两个string之间的差异,你可以使用String :: Diff 。