开发者

nested regex replacements (tag wrapping)

I need to make multiple (nested) text replacements (e.g. wrap all found strings with tag SPAN for highlighting purposes) with a bunch of regular expressions, but... see code:

<?php

// Sample workaround code:
$html = "hello world";

$regex_arra开发者_运维问答y = array(
    '/world/i',
    '/hello world/i'
);

foreach ( $regex_array as $regex ) {
    if ( preg_match_all($regex, $html, $matches) ) {
        foreach ( $matches[0] as $match ) {
            $html = str_replace($match, '<span>' . $match . '</span>', $html);
        }
    }
}

print '<h4>Result:</h4>' 
. htmlentities($html, ENT_QUOTES, 'utf-8');
print '<h4>Expected result:</h4>'
. htmlentities('<span>hello <span>world</span></span>', ENT_QUOTES, 'utf-8');

The result is:

hello <span>world</span>

but the expected result is:

<span>hello <span>world</span></span>

How can I do that?

Yes, I could change the order of regex rules and it could solve the problem, but I really CAN NOT DO THAT!


You should use preg_replace_callback instead of preg_match_all + str_replace:

function handle_matches($matches) {
    return '<span>' . $matches[0] . '</span>';
}
foreach ( $regex_array as $regex ) {
    $html = preg_replace_callback($regex, 'handle_matches', $html);
}

Or with PHP5.3:

foreach ( $regex_array as $regex ) {
    $html = preg_replace_callback($regex, function($matches) {
        return '<span>' . $matches[0] . '</span>';
    }, $html);
}

For the tag order problem, there is no real solution is you can't change there order or modify them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜