这是我的困境:
我写了这个RegEx模式,它在我的沙箱中有效但在我的网站上不起作用:
沙箱:http://regex101.com/r/vP3uG4
模式:
(.*[$]'.$variable.'\s*=\s*\'?)(.*?)(\'?;.*)
代码行如下:
$savedsettings_new = preg_replace('/(.*[$]'.$variable.'\s*=\s*\'?)(.*?)(\'?;.*)/is','$1'. $value .'$3',$savedsettings_temp);
正如您所看到的,它可以在沙盒上运行,但它不能正常工作。
我试图匹配可以表示为字符串的变量值(带有单引号)或没有引号的数值,如下所示:
$match_string = 'value';
$match_number = 1;
现在这个代码可以正常使用字符串,但是数字变量没有包含在字符串中我只是获得后向引用$ 3的内容而且之前我什么都没得到!
我正在摸不着头脑,真的无法弄清楚为什么它在RegEx101上工作但不能正常工作......当我匹配一个或没有单引号时,我不是做正确的事情(并且因为preg_replace而逃避它们有报价?
答案 0 :(得分:2)
好的,发现了这个问题。解决方案是将反向引用包装在${}
。
引用PHP manual:
当使用替换模式时,后向引号后面紧跟另一个数字(即:在匹配的模式后立即放置一个文字数字),您不能使用熟悉的
\\1
表示法进行反向引用。例如,\\11
会混淆preg_replace(),因为它不知道您是否希望\\1
反向引用后跟文字1
,或\\11
反向引用后跟无效。在这种情况下解决方案是使用\${1}1
。
因此,您的代码应如下所示:
header('Content-Type: text/plain');
$variable = 'tbs_development';
$value = '333';
$savedsettings_temp = <<<'CODE'
$tbs_underconstruction = 'foo';
$tbs_development = 0;
CODE;
$pattern = '/(.*[$]'.preg_quote($variable).'\s*=\s*\'?)(.*?)(\'?;.*)/is';
$replacement = '${1}'.$value.'${3}';
$savedsettings_new = preg_replace($pattern, $replacement, $savedsettings_temp);
echo $savedsettings_new;
输出:
$tbs_underconstruction = 'foo';
$tbs_development = 333;
答案 1 :(得分:1)
如果变量$value
包含数值,那么preg_replace
中的替换模式将如下所示:$12$3
这是真的但不像你预期的那样。在Regex Engine中,$ddd
或此处$dd
(等于\ddd
和\dd
)被视为八进制数。
因此,在这种情况下,$12
表示八进制索引12,它等于ASCII中的一种空格。
如果在正则表达式中处理这些棘手的问题,您应该将您的反引用号码包含在{}
内,这样它应该是${1}2${3}
将替换模式更改为'${1}'.$value.'${3}'