使用perl index()函数进行精确模式匹配

时间:2012-12-11 10:17:58

标签: perl

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

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

我的搜索字符串为KEY=CAT

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

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

这让我觉得它可能不是那么简单,但我的perl技能是有限的:)。是否有可能做我想做的事情?

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

5 个答案:

答案 0 :(得分:3)

您需要了解Perl中的Regular Expressions。 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";
}

但是,这两者都匹配:

  • 不要让猫从包中取出
  • Sears目录到达邮件

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

 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";
}

但是,这些呢?

  • 单词CAT全部大写
  • 愚蠢的猫
  • Cat!Here Cat!Common Cat!”:“cat”后的标点符号
  • 不要让'猫'脱离'包':”cat“周围的引号

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

然而:

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

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

事实上,Perl的正则表达式使得Perl成为一种流行的语言。

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

希望这有帮助。

答案 1 :(得分:2)

怎么样:

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

答案 2 :(得分:2)

这是({1}}

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

如你所见,它有点罗嗦,因为它只使用基本的Perl字符串函数 - 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"; } index。检查找到的子字符串是否确实是一个单词是通过检查其下一个和前一个字符(如果它们存在)来完成的:如果它们属于substrA-Z范围,则它不是一个单词。

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

a-z

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

现在考虑一下:

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

......就是这样!模式字面上测试给定的字符串给定的字符串($ test)给定($ key)前面或后面跟着A-Za-z范围的符号,并且支持Perl正则表达式魔法(this variable,特别是)可以很容易地获得这种子串的起始位置。

底线:使用正则表达式来执行正则表达式的工作。

答案 3 :(得分:1)

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

my $string = "CATALOG SCATTER CAT CATHARSIS";
index($string, 'CAT');
如果$string包含字符CAT,则

将返回零或更高,正常表达式如

$string =~ /\bCAT\b/;

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

答案 4 :(得分:-1)

使用\ E值。 所以:

#!usr/bin/perl

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

if($string =~ m/$check\E/g)
{
print "match";
}
else 
{ 
die("No Match"); 
}