I have some XML chunk returned by DOMDocument::saveXML(). It’s already pretty indented, with two spaces per level, like so:
<?xml version="1.0"?>
<root>
<error>
<a>eee</a>
<b>sd</b>
</error>
</root>
As it’s not possible to configure DOMDocument (AFAIK) about the indentation character(s), I thought it’s possible to run a regular expression and change the indentation by replacing all two-space-pairs into a tab. This can be done with a callback function (Demo):
$xml_string = $doc->saveXML();
function callback($m)
{
$spaces = strlen($m[0]);
$tabs = $spaces / 2;
return str_repeat("\t", $tabs);
}
$xml_string = preg_replace_callback('/^(?:[ ]{2})+/um', 'callback', $xml_string);
I’m now wondering if it’s possible to do this w/o a callback function (and without the e-modifier (EVAL)). Any regex wizards with an idea?
You can use
\G:Did some benchmarks and got following results on Win32 with PHP 5.2 and 5.4:
Surprising that callback is faster than than
\Gin PHP 5.4 (altho that seems to depend on the data,\Gis faster in some other cases).For
\G/^ |\G /mis used, and is a bit faster than/(?:^|\G) /m./(?>^|\G) /mis even slower than/(?:^|\G) /m./u,/S,/Xswitches didn’t affect\Gperformance noticeably.The
whilereplace is fastest if depth is low (up to about 4 indentations, 8 spaces, in my test), but then gets slower as the depth increases.The following code was used: