我有一个find_replace子例程,它接受参数(内容,查找正则表达式,替换正则表达式,结果变量来存储结果)。我使用qr//
传递查找和替换正则表达式。查找正则表达式效果很好,但替换正则表达式并不适用。
$text = "11 22 33 44 55";
find_replace($text,qr/(33 )(.*?)( 55)/,qr/$1<BOLD>$2<\/BOLD>$3/,my $newText);
print $newText;
#Should print: 11 22 <I>33 <B>44</B> 55</I>
#But it prints: 11 22 <I>(?^:<B></B>)</I>
sub find_replace {
my $content = shift;
my $findRegEx = shift;
my $replaceRegEx = shift;
my $newVariable = \shift;
${$newVariable} = $content;
${$newVariable} =~ s/$findRegEx/<I>$replaceRegEx<\/I>/g;
}
我找到了解决此问题的方法:
$text = "11 22 33 44 55";
find_replace($text,qr/(33 )(.*?)( 55)/,sub{"$1<B>$2<\/B>$3"},my $newText);
print $newText;
#Prints: 11 22 <I>33 <B>44</B> 55</I>
sub find_replace {
my $content = shift;
my $findRegEx = shift;
my $replaceRegEx = shift;
my $newVariable = \shift;
${$newVariable} = $content;
${$newVariable} =~ s($findRegEx){ "<I>".$replaceRegEx->()."<\/I>" }ge;
}
但此修补程序使用sub{"…"}
而不是qr/…/
。我正在寻找的是继续使用qr//
来传递替换正则表达式并获得相同的结果。
答案 0 :(得分:3)
首先,使用qq//
替换表达式是没有意义的,因为替换表达式不是正则表达式模式。 q//
(双引号字符串)和s/$findRegEx/<I>$replaceRegEx<\/I>/g
(单引号字符串)用于构造字符串。
主要问题是
my $repl_expr = sub { qq/<I>$replaceRegEx<\/I>/ }; # Interpolates $replaceRegEx
s/$findRegEx/ $repl_expr->() /eg
装置
my $repl_expr = sub { qq/$1<B>$2<\/B>$3/ }; # Interpolates $1, $2 and $3
s/$findRegEx/ $repl_expr->() /eg
但你真的想要
use String::Substitution qw( gsub_copy );
my $newText = gsub_copy($text, qr/(33 )(.*?)( 55)/, '$1<BOLD>$2</BOLD>$3');
如果您需要从字符串开始(例如,替换表达式来自配置文件),那么您可以通过以下方式实现所需:
if ($args[0] instanceof ActiveRecordField) // False
if ($args[0] instanceof \MyCompany\Classes\ActiveRecordField) // True
答案 1 :(得分:1)
你必须明白,替换中的文本不是正则表达式,而是一个准备插入的字符串。因此,您必须执行诸如解决方法之类的操作,以便延迟插值,直到正则表达式针对所需的字符串运行。
话虽这么说,如果你的sub就像这样简单,我不确定你真的应该把它放在一个子 - s
运算符已经是一个子调用,而你&#39;只是使事情复杂化。当然,在某些情况下,您需要将正则表达式或其他任何内容传递给更复杂的子项,这可能是一件好事,但您仍然需要这种类型的延迟插值才能使其工作。