0

我正在努力在 Perl 中使用正则表达式来匹配带有可选前缀和后缀的字符串。

到目前为止,这是我的表达:

my $string = "prefix1_foo_suffix2";
if ($string =~ m/^(prefix1_|prefix2_)?(prefix3_|prefix4_)?foo|bar(_suffix1|_suffix2)?$/) {
  print "match"
};

所以这应该匹配像这样的字符串

prefix1_foo_suffix2
prefix1_prefix4_bar
bar_suffix2

但不是

prefix1_baz_suffix2
bar_suffix42

不过,据我所知,这匹配任何后缀(即:“foo”或“bar”之后的任何内容)。关于我做错了什么的任何想法?

4

1 回答 1

4

您的正则表达式存在优先级问题。此外,对于非捕获组,您应该使用(?:group).

这是你写的:

m/  (?: ^ (?: prefix1_ | prefix2_ )? (?: prefix3_ | prefix4_ )? foo )
  | (?: bar (?: _suffix1 | _suffix2 )? $ )
/x

但你的意思是:

m/  \A
    (?: prefix1_ | prefix2_ )?
    (?: prefix3_ | prefix4_ )?
    (?: foo      | bar      )
    (?: _suffix1 | _suffix2 )?
    \z
/x

快速测试:

my $regex = qr/
    \A
    (?: prefix1_ | prefix2_ )?
    (?: prefix3_ | prefix4_ )?
    (?: foo      | bar      )
    (?: _suffix1 | _suffix2 )?
    \z
/x;
say "$_:\t", ($_ =~ $regex ? "passes" : "doesn't match") for
  qw/prefix1_foo_suffix2
     prefix1_prefix4_bar
     bar_suffix2
     prefix1_baz_suffix2
     bar_suffix42
  /;

输出:

prefix1_foo_suffix2:    passes
prefix1_prefix4_bar:    passes
bar_suffix2:            passes
prefix1_baz_suffix2:    doesn't match
bar_suffix42:           doesn't match
于 2013-03-19T23:55:56.483 回答