【问题标题】:Perl regular expression inside regular expression正则表达式中的 Perl 正则表达式
【发布时间】:2016-10-25 19:50:56
【问题描述】:

我想问是否可以在带有“e”修饰符的替换匹配表达式的 RHS 中放置另一个正则表达式。

例如,我想将 $foo 中存储的任何单词替换为 相同数量的“-”,不区分大小写。

例如:

$str =~ s/($foo)/$temp = $1; $temp ~= s/./-//gie;

但是编译的时候经常报语法错误,而

$str =~ s/($foo)/$temp = $1; $temp = "---"/gie; 

确实有效。

我想我没有正确地避开斜线,有什么想法吗?

【问题讨论】:

  • 只需更改分隔符:s/.../$&=~s%...%...%r/e(您当然需要/e 修饰符)。不过,您的代码很奇怪,也许您应该多解释一下您要做什么,以便我们提供更多帮助。特别是,$1 是 undef,即使它被定义,如果没有 /r 修饰符,你的嵌套正则表达式也是无用的。
  • 非常感谢! s%%%r 表达式运行良好。这正是我一直在寻找的,而我在其他文档中没有找到。
  • @VittVolt:% 的意义在于它与主要封闭正则表达式中使用的/ 不同。您也可以使用其他正则表达式分隔符。

标签: regex perl expression


【解决方案1】:

您当然需要e 修饰符才能使用

$str = 'banana';
$foo = 'na';
$str =~ s/$foo/$&=~s#.#-#gr/ge;
print $str;

online Perl demo

请注意,外部正则表达式使用/ 正则表达式分隔符,而内部正则表达式包含不同的分隔符(您可以在此处使用您最喜欢的两个)。

e 修饰符对于外部模式是必需的,您还需要将r 修饰符传递给内部模式以避免只读值的修改问题。

还要注意,在 Perl v.5.20 之前,您最好避免使用 $& 并将整个模式用 (...) 捕获组括起来:

$str =~ s/($foo)/$1=~s#.#-#gr/ge;
          ^    ^ ^^ 

【讨论】:

  • cool,我一直习惯在这种情况下使用sub.. 没想到使用r 标志... 也可以在需要时使用tr 与相同的@ 987654335@标志
  • 我之前是用$str=~s/$foo/my $tmp=$&; $tmp=~s#.#-#g; ($tmp);/ge;这个方法,但是$str =~ s/($foo)/$1=~s#.#-#gr/ge;的代码太棒了。
  • @Zaid:如果您只需要替换匹配项中的特定子模式,它将不起作用。所以,“笨拙”在这里不合适,我的回答是针对当前问题的通用答案(实际上,我认为 OP 正在寻找这样一个通用的解决方案,否则,我会以 stackoverflow.com/q/17866072/176646 的欺骗而关闭)。
  • @WiktorStribiżew 不确定您所说的更复杂的任务是什么意思。不能定义my $foo = "f..|t..";吗?
【解决方案2】:

这里不需要将s/// 嵌套在另一个s///

我知道这并没有回答问题,而是回答了需求:

$_ = "footastic Funtastic Fantastic";
my $foo = "f..";
s/($foo)/'-' x length($1)/gie;
print;  # ---tastic ---tastic ---tastic

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
相关资源
最近更新 更多