Php 当字符串变量以数字开头时,替换标记中的值时遇到问题

Php 当字符串变量以数字开头时,替换标记中的值时遇到问题,php,regex,string,preg-replace,Php,Regex,String,Preg Replace,我有一些代码,如果$subtitle1的值只包含字母或空格,则正则表达式替换可以正常工作。当$subtitle1字符串以数字开头(例如“第三版”)时,preg_replace函数意外工作。如果我在替换字符串中添加一个空格,那么$subtitle1的值可以以一个数字开头,并且是ok,但在“第三版”中,它会在3之前添加一个不需要的空格 $raw_xml='Linux不仅仅是一个shell'; $subtitle1=‘第三版’; $replacers=数组( “/()([1-9A-Za-z]+)()/

我有一些代码,如果
$subtitle1
的值只包含字母或空格,则正则表达式替换可以正常工作。当
$subtitle1
字符串以数字开头(例如“第三版”)时,preg_replace函数意外工作。如果我在替换字符串中添加一个空格,那么$subtitle1的值可以以一个数字开头,并且是ok,但在“第三版”中,它会在3之前添加一个不需要的空格

$raw_xml='Linux不仅仅是一个shell';
$subtitle1=‘第三版’;
$replacers=数组(
“/()([1-9A-Za-z]+)()/”=>sprintf($1%s$3),$subtitle1),//1
“/()([1-9A-Za-z]+)()/”=>sprintf($1%s$3),$subtitle1),//2
“/()([1-9A-Za-z]+)()/”=>sprintf($1%s$3),$subtitle1),//3
);
echo preg_replace(数组_键($replaces)、数组_值($replaces)、$raw_xml);
//1(当$subtitle1=第三版时,输出:第三版)
//2(当$subtitle1=第三版时,输出:第三版)
//3(当$subtitle1=第三版时,输出:第三版)

如果
$subtitle1
var的类型始终是字符串,我是否可以采取不同的方法使其工作相同?我试过修饰词s,U,但没有进一步的改进。感谢您对此的深入了解。

问题在于:
sprintf($1%s$3,$subtitle1)

输出:
第13版$3

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

好消息是,我为你找到了一个解决方案

替换:
$subtitle1=“第三版”


作者:
$subtitle1='>3rdedition问题在于:
sprintf($1%s$3,$subtitle1)

输出:
第13版$3

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

好消息是,我为你找到了一个解决方案

替换:
$subtitle1=“第三版”


By:
$subtitle1='>3rd Edition在纯理论层面上,您的代码不起作用,导致解析器在sprintf或pcre regex引擎对字符串求值之前,搜索反向引用
$1
$3
作为变量

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

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)

但是要想获得可靠的解决方案,请避免使用regex解析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或pcre正则表达式引擎计算字符串之前,搜索反向引用
$1
$3
作为变量

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

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)

但是要想获得可靠的解决方案,请避免使用regex解析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

谢谢。我已经相应地修改了模式,现在它按预期工作。没有添加“>”和“%s谢谢。我已经相应地修改了模式,现在它可以按预期工作。没有添加“>”和“%s谢谢你的建议。它可以工作,将来我将探索使用SimpleXMLElement。谢谢你的建议。它可以工作,将来我将探索使用SimpleXMLElement。