Perl中的多个模式的字符串匹配

Posted

技术标签:

【中文标题】Perl中的多个模式的字符串匹配【英文标题】:String matching in Perl for multiple patterns 【发布时间】:2020-10-17 09:38:13 【问题描述】:

我有一个字符串,当我用变量检查它时,它没有给我预期的结果。通过使用模式匹配机制,它可以正常工作。

这是 Perl 中的预期行为。如果不是,如何在不使用模式匹配的情况下解决此问题。

代码如下:

#!/usr/bin/perl

use strict; 
use warnings;

my $day_of_week = "Monday";

if (($day_of_week ne "Monday") or ($day_of_week ne "Tuesday"))
    print "In If. Today is $day_of_week.\n";
 else 
    print "In else part\n";

这应该给出如下输出:

In else part

但它给了我:

In If. Today is Monday.

当我使用如下模式匹配更改if 条件时,它工作正常。

if ($day_of_week !~ /Monday|Tuesday) 

我担心的是为什么字符串匹配不符合条件。我在这里做错了吗?

【问题讨论】:

我认为你的意思是 if (not (($day_of_week eq "Monday") or ($day_of_week eq "Tuesday"))) ,而不是你写的:if (($day_of_week ne "Monday") or ($day_of_week ne "Tuesday")) @HåkonHægland 你是对的。这意味着多个模式不适用于ne 条件? ne :如果左参数是字符串不等于右参数,则返回 true。 or :称为逻辑或运算符。如果两个操作数中的任何一个不为零,则条件为真。在您的情况下 ("$day_of_week" ne "Monday") 返回零,但对于这种情况 `("$day_of_week" ne "Tuesday") 返回 1,因此条件变为真。 and: 运算符:称为逻辑与运算符。如果两个操作数都为真,则条件为真。 $foo ne 'bar' or $foo ne 'baz' 之类的东西总是正确的;如果任一操作数为真,则 or 表示真,并且 $foo 始终是 ne 至少您的多项选择之一 【参考方案1】:

是复杂的复合条件让你受益——

$day_of_week ne "Monday"  # FALSE but 
$day_of_week ne "Tuesday" # TRUE

所以你正在测试

if (FALSE or TRUE)  #--> true

这就是为什么建议尝试始终“理顺”这些条件的原因。

所以要测试它既不是星期一也不是星期二

if ( $day_of_week ne "Monday" and $day_of_week ne "Tuesday" )

这更难混淆。


您可能需要将逻辑编码为

if (not ($day_of_week eq "Monday" or $day_of_week eq "Tuesday") )

形成一个大的复合条件然后被否定通常比替代方案更清楚,但在我看来不是这种情况。

【讨论】:

【参考方案2】:

以下内容总是正确的:

不是星期一,或者不是星期二

星期一不是星期二,所以这是真的 (F OR T = T) 星期二不是星期一,所以这是真的 (T OR F = T) 星期三,两者都不是 (T OR T = T)

你想要

不是星期一,也不是星期二

if ($day_of_week ne "Monday" && $day_of_week ne "Tuesday") 
    print "Today is $day_of_week.\n";
 else 
    print "Otherwise\n";

if ($day_of_week eq "Monday" || $day_of_week eq "Tuesday") 
    print "Otherwise\n";
 else 
    print "Today is $day_of_week.\n";


当我用下面的模式匹配更改 if 条件时,它工作正常。

那是因为

现在不是星期一或星期二

不一样

不是星期一,也不是星期二

我们可以证明这一点。

$day_of_week !~ /Monday|Tuesday/

等价于

!( $day_of_week =~ /Monday|Tuesday/ )

相当于

!( $day_of_week =~ /Monday/ || $day_of_week =~ /Tuesday/ )

相当于

!( $day_of_week =~ /Monday/ ) && !( $day_of_week =~ /Tuesday/ )

(根据De Morgan's law)

相当于

$day_of_week !~ /Monday/ && $day_of_week !~ /Tuesday/

请注意如何使用 AND,但您使用的是 OR。

【讨论】:

以上是关于Perl中的多个模式的字符串匹配的主要内容,如果未能解决你的问题,请参考以下文章

perl中每行有多个要匹配的字符串怎么取?

perl学习模式匹配与正则表达式

perl正则表达式

Perl 中的正则表达式组:如何从正则表达式组中捕获与字符串中出现的未知数量/多个/变量匹配的元素到数组中?

是否有 Perl 快捷方式来计算字符串中的匹配数?

perl模糊匹配文件名