3

I am having a problem with bit of code.

This is the code

$test ='<number>1<number>2</number>3</number>';

$i=0;
$find[$i]="#<number>(.*)</number>#is";
$replace[$i]="5";

$i++;
$find[$i]="#<number>(.*)</number>#is";
$replace[$i]="$1";


echo htmlentities(preg_replace($find, $replace, $test));

At the moment this displays just the numnber 5 in the results. But i want it to display 153 Does anyone know what I am doing wrong? thanks

noodles
  • 43
  • 3
  • 2
    Obligatory: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – nickf Jun 27 '12 at 12:53
  • @nickf: This is not HTML, and the scope of the question suggests that plopsie already knows that dealing with nested structures in regex usually means having to work from the inside out iteratively. – Tim Pietzcker Jun 27 '12 at 12:58
  • Indeed, it is XML, even worse. – Wrikken Jun 27 '12 at 13:18
  • 1
    `$domxpath->query('//number/number')->item(0)->textContent = '5';` – Wrikken Jun 27 '12 at 13:20
  • @Wrikken please make this an answer so it can get the upvotes it desperately needs. – nickf Jun 27 '12 at 22:08
  • @nickf: hehe, I have so little faith left I did not even try.. actually, it should be (1) `->nodeValue` there, and (2) as long as `LIBXML_NOXMLDECL` is still not implemented, I've given up trying (yes, workarounds like `$dom->saveXML($dom->documentElement);` exist... But feel hackish. – Wrikken Jun 27 '12 at 22:29

3 Answers3

4

Yes, since .* matches everything (including the tags), you're matching too much. If you restrict your regex not to match across tag boundaries by preventing it from matching angle brackets, you get the desired result:

$test ='<number>1<number>2</number>3</number>';

$i=0;
$find[$i]="%<number>([^<>]*)</number>%is";
$replace[$i]="5";

$i++;
$find[$i]="%<number>([^<>]*)</number>%is";
$replace[$i]="$1";
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
1

Change the first replacement pattern to this:

$find[$i] = "#<number>\d+<number>(.*)</number>\d+</number>#is";
Jeroen
  • 13,056
  • 4
  • 42
  • 63
0
$s ='<number>1<number>2</number>3</number>'; 
echo preg_replace('#<number>(\d+)<number>\d+</number>(\d+)</number>#', "$1 5 $2", $s);

Test code here.

Ωmega
  • 42,614
  • 34
  • 134
  • 203