0

我正在尝试使用 index() 函数,并且我想在字符串中找到单词的位置,只有当它完全匹配时。例如:

我的字符串是STRING="CATALOG SCATTER CAT CATHARSIS"

我的搜索字符串是KEY=CAT

我想说一些类似index($STRING, $KEY)并检查 CAT 的匹配,而不是 CATALOG。我该如何做到这一点?文件说

index 函数在另一个字符串中搜索一个字符串,但没有完整正则表达式模式匹配的类似通配符的行为。

这让我觉得这可能不是那么直截了当,但我的 perl 技能是有限的 :)。有可能做我想做的事吗?

希望我能够很好地表达我的问题。在此先感谢您的帮助!

4

5 回答 5

3

您需要了解Perl 中的正则表达式。Perl 并没有发明正则表达式,而是极大地扩展了这个概念。事实上,许多其他编程语言专门讨论使用Perl 正则表达式

正则表达式匹配特定的单词模式。例如,/cat/匹配字符串中的序列cat

if ( $string =~ /cat/ ) {
    print "String contains the letters 'cat' in a row\n";
}

在许多方面,这与以下内容相同:

my $location = index ( $string, "cat" );
if ( $location =! -1 ) {  # index returns -1 when substring isn't found
    print "String contains the letters 'cat' in a row\n";
}

但是,这两者都会匹配:

  • "Don't let the cat out of the bag"
  • "The Sears catalog arrived in the mail"

你不想匹配最后一个。所以,你可以这样做:

 my $location = index $string, " cat ";

现在,index $string, " cat "不会匹配单词目录。结案!或者是吗?关于什么:

  • "cat and dog it doth rain."

如果句子以“ cat ”开头,也许您可​​以检查并说一切正常:

if ( (index ($string, " cat ") != -1) or (index ($string, "cat") = 0) ) {
    print "String contains the letters 'cat' in a row\n";
}

但是,这些呢?

  • "The word CAT in all uppercase"
  • "Stupid cat"
  • "Cat! Here Cat! Common Cat!":“猫”字后的标点符号
  • "Don't let the 'cat' out of the 'bag'":“猫”周围的引号

可能需要几十行来指定这些条件中的每一个。

然而:

if ( $string =~ /\bcat\b/i ) {
    print "String contains the word 'cat' in it\n";
}

指定每一个 - 然后是一些。说这\b是一个单词边界。这可以是空格、制表符、引号、行的开头或结尾。因此/\bcat\b/指定 this 应该是单词cat而不是catalog。最后i的 告诉您的正则表达式在匹配时忽略大小写,因此您会找到Cat, cat, CAT,cAt和所有其他可能的组合。

事实上,正是 Perl 的正则表达式使 Perl 成为如此流行的语言。

幸运的是,Perl 没有一个,而是两个关于正则表达式的教程:

希望这可以帮助。

于 2012-12-11T13:14:42.633 回答
3

怎么样:

my $str = "CATALOG SCATTER CAT CATHARSIS";
my $key = "CAT";
if ($str =~ /\b$key\b/) {
    say "match at char ",$-[0];;
} else {
    say "no match";
}

输出:

match at char 16
于 2012-12-11T12:17:32.247 回答
2

这是这个问题的(部分)解决方案index

use warnings;
use strict;

my $test = 'CATALOG SCATTER CAT CATHARSIS';
my $key = 'CAT';

my $k_length = length $key;
my $s_length = (length $test) - $k_length;

my $pos      = -1;
while (($pos = index $test, $key, $pos + 1) > -1) {
  if ($pos > 0) {
    my $prev_char = substr $test, $pos - 1, 1;
    ### print "Previous character: '$prev_char'\n";
    next if $prev_char ge 'A' && $prev_char le 'Z'
         || $prev_char ge 'a' && $prev_char le 'z';
  }
  if ($pos < $s_length) {
    my $next_char = substr $test, $pos + $k_length, 1;
    ### print "Next character: '$next_char'\n";
    next if $next_char ge 'A' && $next_char le 'Z'
         || $next_char ge 'a' && $next_char le 'z';
  }
  print "Word '$key' found at " . $pos + 1 . "th position.\n";
}

如您所见,它有点罗嗦,因为它只使用基本的 Perl 字符串函数——index而且substr——。检查找到的子字符串是否确实是一个词是通过检查它的下一个和前一个字符(如果它们存在)来完成的:如果它们属于任何一个A-Za-z范围,它就不是一个词。

您可以通过尝试小写这些字符(使用 lc)来简化它,然后仅检查单个字符范围:

my $lc_prev_char = lc( substr $test, $pos - 1, 1 );
next if $lc_prev_char ge 'a' && $lc_prev_char le 'z';

...但话又说回来,这是一个很小的改进(如果有改进的话)。

现在考虑一下:

my $test = 'CATALOG SCATTER CAT CATHARSIS CAT';
my $key = 'CAT';
while ($test =~ /(?<![A-Za-z])$key(?![A-Za-z])/g) {
  print "Word '$key' found at " . ($-[0] + 1) . "th position.\n";
}

……就是这样!该模式从字面上测试给定的字符串 ($test) 是否为给定的子字符串 ($key) 前面或后面没有 A-Za-z 范围的符号,并且支持 Perl 正则表达式魔法(特别是这个变量)使得很容易得到这样的子串的起始位置。

底线:使用正则表达式来完成正则表达式的工作。

于 2012-12-11T12:29:39.977 回答
1

正则表达式允许搜索包含单词边界以及不同的字符。尽管

my $string = "CATALOG SCATTER CAT CATHARSIS";
index($string, 'CAT');

$string如果包含字符,将返回零或更大CAT,正则表达式如

$string =~ /\bCAT\b/;

将返回false,因为$string不包含CAT前后的单词边界。(单词边界是字符串的开头或结尾,或者介于单词字符和非单词字符之间。单词字符是任何字母数字字符或下划线。)

于 2012-12-11T12:16:41.767 回答
-1

使用 \E 值。所以 :

#!usr/bin/perl

my $string ="Little Tony";
my $check = "Ton";

if($string =~ m/$check\E/g)
{
print "match";
}
else 
{ 
die("No Match"); 
}
于 2012-12-11T11:47:57.850 回答