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

Regex 匹配任何以pre开头并以al结尾的单词的正则表达式,regex,perl,Regex,Perl,在Notepad++编辑器中尝试时,下面的正则表达式给出了正确的结果,但在下面的perl程序中尝试时,我得到了错误的结果。请给出正确的答案和解释 我用于测试模式的文件链接如下: () 正则表达式:^Pre(.*)al(\s*)$ Perl程序: use strict; use warnings; sub print_matches { my $pattern = "^Pre(.*)al(\s*)\$"; my $file = shift; open my $fp, $

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

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

()

正则表达式:^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;
使用严格;
使用警告;
子打印匹配{
my$pattern=“^Pre(.*)al(\s*)\$”;
我的$file=shift;
打开我的$fp$文件;
while(我的$line=){
如果($line=~m/$pattern/){
打印$行;
}
}
}
打印匹配@ARGV;
一些想法:

  • 你不应该逃避美元符号
  • 空格周围的捕获组是无用的
  • 点周围的捕获组也一样
这导致:

^Pre.*al\s*$
如果您不希望像
precious final
这样的单词匹配(由于中间有空格,请将regex更改为:

^Pre\S*al\s*$
代码中包括:

while(my $line = <$fp>) {
        if($line =~ /^Pre\S*al\s*$/m) {
            print $line;
        }
    }
while(我的$line=){
如果($line=~/^Pre\S*al\S*$/m){
打印$行;
}
}
一些想法:

  • 你不应该逃避美元符号
  • 空格周围的捕获组是无用的
  • 点周围的捕获组也一样
这导致:

^Pre.*al\s*$
如果您不希望像
precious final
这样的单词匹配(由于中间有空格,请将regex更改为:

^Pre\S*al\s*$
代码中包括:

while(my $line = <$fp>) {
        if($line =~ /^Pre\S*al\s*$/m) {
            print $line;
        }
    }
while(我的$line=){
如果($line=~/^Pre\S*al\S*$/m){
打印$行;
}
}

在将模式作为正则表达式使用之前,先将其分配给变量,然后再将其放入双引号字符串中,这会把您弄得一团糟

这就是为什么需要转义
$
,因为在双引号字符串中,裸
$
表示要插入变量的值。(例如,
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
(quote regex)操作符,而不是单引号或双引号,尽管如果稍后打印出来以验证regex的内容(我认为这就是为什么您首先将其放入变量中的原因),这会降低可读性:

当然,也可以不把它放在变量中,而是用

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

在将模式作为正则表达式使用之前,先将其分配给变量,然后再将其放入双引号字符串中,这会把您弄得一团糟

这就是为什么需要转义
$
,因为在双引号字符串中,裸
$
表示要插入变量的值。(例如,
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
(quote regex)操作符,而不是单引号或双引号,尽管如果稍后打印出来以验证regex的内容(我认为这就是为什么您首先将其放入变量中的原因),这会降低可读性:

当然,也可以不把它放在变量中,而是用

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

尝试删除尾随换行符:

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

而且,如果要同时匹配
Pre
Pre
,请执行不区分大小写的匹配:

/^Pre\w*al$/i

尝试删除尾随换行符:

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

而且,如果要同时匹配
Pre
Pre
,请执行不区分大小写的匹配:

/^Pre\w*al$/i

不要转义美元符号是否确定?如果这样做,我会出现以下错误。在ex2.pl第8行,Final$应该是\$或$name,在ex2.pl第8行,靠近“=”^Pre(.*)al(\s*)$”的字符串内语法错误实际上,OP在这一点上是正确的。
$
需要转义,因为它是双引号字符串,而不是正则表达式模式。
“^Pre(.*)al(\s*)\$”
(需要转义)与
/^Pre(.*)al(\s*)$/
(不要转义)。顺便说一句,如果要将模式作为常规字符串分配给变量,则如果使用单引号而不是双引号,则无需转义
$
。我回滚了您的编辑,因为它完全改变了问题,因此没有任何答案有意义。编辑您的问题是可以的,但请确保您不这样做当您这样做时,不要使现有答案无效。而且,
$foo=m/bar/;
不会做您认为它会做的事情;您的意思是
$foo=qr/bar/;
@ThisSuitesBlack:明白了。谢谢:)不要转义美元符号你确定吗?如果我这样做,我会得到以下错误。在ex2.pl第8行,Final$应该是\$或$name,在ex2.pl第8行,靠近“=”^Pre(.*)al(\s*)$)$”的字符串语法错误实际上,OP在这一行上是正确的。
$
需要使用esc