Honchar Denys
Honchar Denys

Reputation: 1508

How can i have counter for php preg_match?

function getContent($xml,$tag,$id="") {
    if ($id=="") {
        $tag_regex = '/<'.$tag.'[^>]*>(.*?)<\/'.$tag.'>/si';
    } else {
        $tag_regex = '/<'.$tag.'[^>]*id=[\'"]'.$id.'[\'"]>(.*?)<\/'.$tag.'>/si';
    }
    preg_match($tag_regex,$xml,$matches);
    return $matches[1];
}

$omg = file_get_contents("Generated/index.php");
$extract = getContent($omg,"div","lolz2");
echo $extract;

For example i have something like this. And html have something like this inside:

<div id="lolz">qwg1eqwe</div>
<div id="lolz1"><div id='lolz2'>qwdqw2cq</div>asd3qwe</div>

If we search for id lolz we get the correct answer, but if we search for lolz1 we stop at first </div> that's inner <div id="lolz2">. It's possible to keep something like counter for preg_match that's will keep how many <div>'s i pass till i find </div>?

Upvotes: 0

Views: 132

Answers (1)

Aram Kocharyan
Aram Kocharyan

Reputation: 20431

HTML isn't a regular language, so building something like that would be overkill and is the job of an HTML parser. Please see: RegEx match open tags except XHTML self-contained tags.

The reason your code was failing however was because you were using both single and double quotes in your input but your regex didn't account for it. This works for me:

function getContent($xml,$tag,$id="") {
    if ($id=="") {
        $tag_regex = '/<'.$tag.'[^>]*>(.*?)<\/'.$tag.'>/si';
    } else {
        $tag_regex = '/<'.$tag.'[^>]*id=[\\\'"]'.$id.'[\\\'"]>(.*?)<\/'.$tag.'>/si';;
    }
    preg_match($tag_regex,$xml,$matches);
    return $matches[1];
}

$omg = '<div id="lolz">qwg1eqwe</div>
<div id="lolz1"><div id="lolz2">qwdqw2cq</div>asd3qwe</div>';
$extract = getContent($omg,"div","lolz2");
var_dump($extract);

As long as you don't have nested elements this code will work and you won't need to use a DOM parser, though you really should for anything more complicated that might be nested (e.g. you don't have control over the input).

Upvotes: 1

Related Questions