Substitute text using match in a non greedy way?
I have a SOAP Call that looks like this:
<?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>
I want to replace REPLACEMEE and REPLACEMETOO with defined values, but in the subject those values can be anything.
I tried theese preg_match rules:
$body = preg_replace('#>.+?</username>#','>myuser</username>',$body);
$body = preg_replace('#>.+?</password>#','>mypw/username>',$body);
But I end up with this string:
<?xml version="1.0" encoding="utf-8"?>myuser</username></tns:login></soap:Body></soap:Envelope>
I cant understand why?
Why is this occouring and how do I need to modify my rules?
Edit:
I already worked my way around it with a negated character class like [^>]+
however I am still intersted in why the non greedyness doesnt work.
The "non greedyness" works as expected.
The first regex started when it encountered >
and then took only the minimum until the first </username>
was reached.
If the XML had been:
<?xml version="1.0"><accnt1><username>foo</username></accnt1><accnt2><username>bar</username></accnt2> ...
Then >.+?</username>
grabs:
><accnt1><username>foo</username>
Whereas >.+</username>
would grab:
><accnt1><username>foo</username></accnt1><accnt2><username>bar</username>
Try:
$body = preg_replace("/(<username[^>]+>).+?(<\/username>)/", "$1new value$2", $input);
$body = preg_replace("/(<password[^>]+>).+?(<\/password>)/", "$1new value..$2", $input);
精彩评论