正则表达式,匹配任何以pre开头并以al结尾的单词

时间:2016-08-14 11:14:18

标签: regex perl

以下正则表达式在Notepad ++编辑器中尝试时给出了正确的结果,但是当尝试使用下面的perl程序时,我得到了错误的结果。请给出正确答案和解释。

我用于测试模式的文件链接如下:

http://sainikhil.me/stackoverflow/dictionaryWords.txt

正则表达式:^ Pre(。*)al(\ s *)$

Perl程序:

use strict;
use warnings;

sub print_matches {
    my $pattern = "^Pre(.*)al(\s*)\$";
    my $file = shift;

    open my $fp, $file;

    while(my $line = <$fp>) {
        if($line =~ m/$pattern/) {
            print $line;
        }
    }
}

print_matches @ARGV;

3 个答案:

答案 0 :(得分:2)

一些想法:

  • 你不应该逃避美元符号
  • 空白周围的捕获组无用
  • .
  • 周围的捕获组相同

导致:

^Pre.*al\s*$

如果您不希望匹配precious final之类的字词(因为中间空格,请将正则表达式更改为:

^Pre\S*al\s*$

包含在您的代码中:

while(my $line = <$fp>) {
        if($line =~ /^Pre\S*al\s*$/m) {
            print $line;
        }
    }

答案 1 :(得分:1)

通过将模式分配给变量,然后将其用作正则表达式并在执行此操作时将其置于双引号字符串中,您就会搞砸了。

这就是你需要转义$的原因,因为在双引号字符串中,裸$表示你想要插入变量的值。 (例如,my $str = "foo$bar";

导致您出现问题的原因是因为\s中的反斜杠被视为转义为s - 这使您只需s

$ perl -E 'say "^Pre(.*)al(\s*)\$";'
^Pre(.*)al(s*)$

因此,当您去执行正则表达式时,它会查找零个或多个s es而不是零个或多个空白字符。

对此最直接的解决方法是逃避反斜杠:

$ perl -E 'say "^Pre(.*)al(\\s*)\$";'
^Pre(.*)al(\s*)$

更好的解决方法是使用单引号而不是双引号,并且不要逃避$

$ perl -E "say '^Pre(.*)al(\s*)$';"
^Pre(.*)al(\s*)$

最好的解决方法是使用qr(引用正则表达式)运算符而不是单引号或双引号,但是如果稍后将其打印出来以验证其内容,那么它会使人的可读性降低一些。正则表达式(我认为这就是为什么你首先将它放入一个变量中):

$ perl -E "say qr/^Pre(.*)al(\s*)$/;"
(?^u:^Pre(.*)al(\s*)$)

或者,当然,根本不要将它放入变量并与

进行匹配
if($line =~ m/^Pre(.*)al(\s*)$/) ...

答案 2 :(得分:1)

尝试删除尾随换行符:

    while(my $line = <$fp>) {
        $line =~ s/[\r\n]+$//s;

并且,要仅匹配以Pre开头且以al结尾的字词,请尝试使用此正则表达式:

/^Pre\w*al$/

\w表示一个单词的任何字母,而不仅仅是任何字符)

并且,如果您想同时匹配Prepre,请执行不区分大小写的匹配:

/^Pre\w*al$/i