繁体   English   中英

当字符串变量以digit开头时,无法替换标签中的值

[英]Having trouble replacing a value in a tag when a string variable starts with digit

我有一些代码,如果$subtitle1的值仅包含字母或空格,则使用正则表达式替换即可。 $subtitle1字符串以数字开头(例如“第三版”)时,preg_replace函数会意外运行。 如果在替换字符串中添加空格,则$ subtitle1的值可以以数字开头并且可以,但是在“ 3rd Edition”中,它在3之前放置了多余的空格。

$raw_xml    = '<property name="subtitle1" type="String">Linux is more than a shell</property>';
$subtitle1  = '3rd Edition';

$replacers  = array (
    '/(<property name="subtitle1" type="String">)([1-9A-Za-z ]+)(<\/property>)/'  => sprintf("$1%s$3",$subtitle1), //1
    '/(<property name="subtitle1" type="String">)([1-9A-Za-z ]+)(<\/property>)/'  => sprintf("$1 %s$3",$subtitle1), //2
    '/(<property name="subtitle1" type="String">)([1-9A-Za-z ]+)(<\/property>)/'  => sprintf("$1%s$3",$subtitle1), //3
);
echo preg_replace(array_keys($replacers), array_values($replacers), $raw_xml);        

//1 (when $subtitle1 = 'Third Edition', outputs: <property name="subtitle1" type="String">Third Edition</property>)
//2 (when $subtitle1 = '3rd Edition', outputs: <property name="subtitle1" type="String"> 3rd Edition</property>)
//3 (when $subtitle1 = '3rd Edition', outputs: rd Edition</property>)

只要$subtitle1 var的类型始终是字符串,我是否可以做些不同的事情来使其工作相同? 我已经尝试过修饰符s,U,但是没有得到更多。 感谢您对此的任何见解。

在纯理论平面上,您的代码无法正常工作,这是因为解析器在sprintf或pcre regex引擎对字符串进行求值之前将反向引用 $1$3作为变量进行搜索。

因此,要使其正常工作,只需替换sprintf文字字符串部分:

sprintf("$1%s$3",$subtitle1) -> sprintf('${1}%s${3}',$subtitle1)
# Note the change of $1 -> ${1} to clearly delimit the backreference
# and the use of single quote string '...' instead of  "..." 
# (inside double quotes any $ start an evaluation as variables of string beside)

但是,为了获得可靠的解决方案,请避免使用正则表达式来解析xml,并使用专门的(简单而强大的)解析器,如下所示:

<?php
$xml = <<<XML
<properties> <!-- Added -->
    <property name="subtitle1" type="String">Linux is more than a shell</property>
</properties>
XML;

$properties = new SimpleXMLElement($xml);
$properties->property[0] = '3rd Edition';

echo $properties->asXML(); //Only the first is changed

在“ 官方文档”中查看更多信息。

问题是因为: sprintf("$1%s$3",$subtitle1)

输出: $13rd Edition$3

我想正则表达式引擎将其理解为第13个捕获组。

好消息是,我为您找到了解决方案。

替换: $subtitle1 = '3rd Edition' ;

通过: $subtitle1 = '>3rd Edition<';

然后像这样从您的第一个和第三个捕获组中提取<>。

$replacers  = array (
    '/(<property name="subtitle1" type="String")>([1-9A-Za-z ]+)<(\/property>)/'  => sprintf("$1%s$3",$subtitle1), //1
    '/(<property name="subtitle1" type="String")>([1-9A-Za-z ]+)<(\/property>)/'  => sprintf("$1 %s$3",$subtitle1), //2
    '/(<property name="subtitle1" type="String")>([1-9A-Za-z ]+)<(\/property>)/'  => sprintf("$1%s$3",$subtitle1), //3
);

您可以在此处进行测试: http : //sandbox.onlinephpfunctions.com/code/05bf9a209bdcd6622bf494dc7f4887660e7a93a0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM