为什么这个Perl正则表达式不起作用?

时间:2009-07-07 07:40:03

标签: regex perl

我有一个Perl脚本,应该匹配这个字符串:

Sometimes, he says "hey fred, what's up?"

它说如果它在单词的开头,结尾或中间发现了fred,或者它只是发现了“fred”。所以它匹配阿尔弗雷德和弗雷德里奇。

嗯,在这个字符串中,它应该说它自己发现了fred,但是它说它发现它在一个单词的开头。这是fred开头的正则表达式(它在if-elsif阶梯的开头,单词的结尾,只是fred,单词的中间):

if(/.*\s+[fF][rR][eE][dD][^ \t\r\n,.:;'"].*/){
    print "found fred at beginning of a word:\n    $_\n";

我使用了[^ \t\r\n,.:;'"]代替\S这个词后跟一些标点符号。显然,这不是一个详尽的标点符号列表,但是这个例子并不重要,因为它后跟一个逗号。

这是一个foreach循环...如果它意味着什么,这是 Learning Perl 第5版的练习7-1。

更新

本书中的练习是编写一个Perl程序,在单词列表中查找“fred”。然后它问,脚本是否在“弗雷德里希”或“阿尔弗雷德?”中找到了弗雷德?然后它会写一个文本文件,讲述Fred Flinstone和他的朋友,并将其用作脚本的输入。

我想通了,有点: 在编写我忘记的问题时,我必须改变一些东西:我再次测试它,而不是匹配单词的开头,它只是说它在任何地方都找到了它。所以问题并不在于它认为它只是在一个词的开头,而是它认为它不是单词中唯一的东西。我将[,.:;'"]?\s+添加到与“fred”匹配的代码作为整个单词并且它有效。我想在问之前我应该​​多考虑一下:)

3 个答案:

答案 0 :(得分:9)

你可以使用\ b作为单词边界,使用\ w作为单词字符,而且,对于不区分大小写的/ i修饰符比使用[fF]等更清晰。

类似的东西:

if ($st =~ m{\b fred \w+ }xi) {
    print "Found fred at the beginning of a word";
} else {
    print "Not found";
}

如果您需要将“fred”作为单词本身查找,请使用\b fred \b

我建议您阅读http://perldoc.perl.org/perlre.html

答案 1 :(得分:2)

你确定它不起作用吗?它看起来很适合您的示例案例,我刚刚运行的稍微调整过的代码版本给出了预期的答案:

#!/usr/bin/perl

use strict; use warnings;

my $st = q{Sometimes, he says "hey fred, what's up?"};

foreach($st)
{
    if(/.*\s+[fF][rR][eE][dD][^ \t\r\n,.:;'"].*/){
        print "found fred at beginning of a word:\n    $_\n";
    }
    else
    {
        print "not found in $_";
    }
}

正在报告'未找到'部分(正如预期的那样,因为我没有进行'刚刚进行'检查)。

答案 2 :(得分:1)

如果您想匹配Fredfrederick而不是Alfred,那么您的正则表达式是:

/\bfred\w*\b/i

也就是说:一个单词边界后跟(case-insentitive)“fred”后跟零个或多个单词字符,后跟另一个单词边界。如果你只想要frederick,但是Fred已经出局,那么:

/\bfred\w+\b/i

,即单词边界,“fred”,一个或多个单词字符,单词边界。

更新:重新阅读你的问题,似乎你想要:

perl -E '
use strict;
use warnings;
for( "nobody is here",
    "I am Frederick Flintsone",
    "she is alfredine",
    "I am Alfred Hitchcock",
    "fred has left the building" ) {
  say;
  if( ! /\b(\w*)fred(\w*)\b/i ) {
    say "no fred!"
  } elsif( ! length "$1$2" ) {
    say "fred by itself!"
  } elsif( ! length $2 ) {
    say "something-fred!"
  } elsif( ! length $1 ) {
    say "fred-something!"
  } else {
    say "something-fred-something!"
  }
}'

输出:

nobody is here
no fred!
I am Frederick Flintsone
fred-something!
she is alfredine
something-fred-something!
I am Alfred Hitchcock
something-fred!
fred has left the building
fred by itself!