【问题标题】:substring match in perl, yes or noperl中的子字符串匹配,是或否
【发布时间】:2018-05-02 04:57:01
【问题描述】:

使用 perl,我想在字符串中查找子字符串。结果是真/假,然后我将决定要做什么。有很好的帖子here,但对我来说用法很模糊。

my $big_string = "Hello Good World";
my $pat = "world";

虽然大写/非大写字母并不重要,但我想得到 True。

use List::Util 'any';
my $match_found = any { /$pat/ } @big_string;
if (match_found)
   print "yes\n";
else
   print "no\n";

正确吗?有没有更好的 API 用于此目的?

【问题讨论】:

  • 您的语法完全错误。您是否尝试过运行此代码?您还在第一个代码块中谈论单个字符串,而在第二个代码块中突然有一个可能的字符串数组。
  • 我只是想尝试编写代码。我知道这可能不正确。
  • 那么您也应该尝试运行它。通常代码编写涉及运行它。至少对我来说。 ;) 如果您不想运行它,您仍然可以使用perl -c 对其进行语法检查。

标签: perl


【解决方案1】:

这是不正确的,因为它甚至不编译:if / else 在 Perl 中总是跟着 { } 块。此外,if (match_found) 缺少变量上的 $ 标记。

如果您真的想要不区分大小写的匹配(即忽略大小写字母之间的差异),您需要在正则表达式中添加i 标志。

最后,您的代码没有定义@big_string 数组,只定义了$big_string 标量。

所以:

use strict;
use warnings;
use List::Util 'any';

my $big_string = "Hello Good World";
my $pat = "world";

my $match_found = any { /$pat/i } $big_string;
if ($match_found) {
   print "yes\n";
} else {
   print "no\n";
}

此代码可以工作,但可以改进。

首先,为什么要使用any?我们没有要检查的多个字符串的列表:

my $match_found = $big_string =~ /$pat/i;

其次,$pat 看起来不像是正则表达式。这是一个普通的字符串。这对字母数字字符(例如world)没有任何区别,但通常我们应该转义字符串中不打算被解释为正则表达式的所有正则表达式元字符。这可以通过quotemeta 函数(或其\Q \E 缩写形式)来完成:

my $match_found = $big_string =~ /\Q$pat\E/i;

这是我们的改进版本:

use strict;
use warnings;

my $big_string = "Hello Good World";
my $pat = "world";

my $match_found = $big_string =~ /\Q$pat\E/i;
if ($match_found) {
   print "yes\n";
} else {
   print "no\n";
}

最后,我们甚至不需要正则表达式来进行简单的子字符串搜索。相反,我们可以这样做:

use feature 'fc';
my $match_found = index(fc($big_string), fc($pat)) >= 0;

fc 实现完整的 Unicode 大小写折叠。

【讨论】:

  • fc 仅在 5.16+ 中可用。
  • 我想我不会在这项工作中使用正则表达式。我想找到一个子字符串匹配。两个字符串都是纯文本,模式是一个完整的单词。
  • @simbabque 5.16 已经推出 5 年了。我同意。 :-)
  • @mahmood 您的代码具有正则表达式模式匹配。 melpomene 只是在纠正您的错误。他们的最后一个例子是纯子字符串匹配。 index 类似于 substr,但在第一次出现时停止并返回位置,而不是字符串。
猜你喜欢
  • 2013-11-19
  • 2014-08-18
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2015-01-11
  • 2020-08-23
相关资源
最近更新 更多