以非贪婪的方式使用匹配替换文本?

时间:2011-06-16 01:05:39

标签: php xml regex preg-match

我有一个SOAP调用,如下所示:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:FileserveAPI" xmlns:types="urn:FileserveAPI/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><tns:login><username xsi:type="xsd:string">REPLACEME</username><password xsi:type="xsd:string">REPLACEMETOO</password></tns:login></soap:Body></soap:Envelope>

我想用定义的值替换REPLACEMEE和REPLACEMETOO,但在主题中这些值可以是任何值。

我尝试过thece preg_match规则:

$body = preg_replace('#>.+?</username>#','>myuser</username>',$body);
$body = preg_replace('#>.+?</password>#','>mypw/username>',$body);

但我最终得到了这个字符串:

<?xml version="1.0" encoding="utf-8"?>myuser</username></tns:login></soap:Body></soap:Envelope>

我不明白为什么?

为什么会出现这种情况?我如何修改规则?

编辑:

我已经用一个否定的角色类[^>]+来解决这个问题,但是我仍然对非贪婪无效的原因感兴趣。

2 个答案:

答案 0 :(得分:1)

尝试:

$body = preg_replace("/(<username[^>]+>).+?(<\/username>)/", "$1new value$2", $input);
$body = preg_replace("/(<password[^>]+>).+?(<\/password>)/", "$1new value..$2", $input);

答案 1 :(得分:1)

“非贪婪”按预期工作。

第一个正则表达式在遇到>时开始,然后只取最小值直到达到第一个</username>

如果XML是:

<?xml version="1.0"><accnt1><username>foo</username></accnt1><accnt2><username>bar</username></accnt2> ...


然后>.+?</username>抓住:

><accnt1><username>foo</username>


>.+</username>会抓住:

><accnt1><username>foo</username></accnt1><accnt2><username>bar</username>