Reg-ex查询太贪心了

时间:2014-11-15 22:14:55

标签: regex

请考虑以下代码段:

<Offering id=1 blah blah templateid=abc something=blah
gretre
rtert
ret
tr
/Offering>

<Offering id=2 blah blah templateid=def something=blah>
gretre
rtert
ret
tr
</Offering>

<Offering id=3 blah blah templateid=ghi something=blah>
gretre
rtert
ret
tr
</Offering>

鉴于我所知道的只是模板ID,我需要返回包含它的整个Offer节点。即对于templateid = def,我需要返回:

   <Offering id=2 blah blah templateid=def something=blah>
    gretre
    rtert
    ret
    tr
    </Offering>

我已经尝试了各种各样的但是我能得到的最接近的是(?s)<Offering.+?templateid=def.+?</Offering>,它从第一个产品返回,直到包含我的模板ID的产品结束。我理解为什么,但我尝试过的任何事情都无法解决。我猜测外观,但我无法做到正确。

如何返回整个产品节点?

3 个答案:

答案 0 :(得分:1)

您可以使用否定修改正则表达式,我也可能使用单词边界。

<Offering[^>]*\btemplateid=def[^>]*>[^<]*</Offering>

如果此标记内有其他标记,则可以执行...

(?s)<Offering[^>]*\btemplateid=def.+?</Offering>

答案 1 :(得分:0)

这应该有用,但请注意我已经转义了/字符,根据您使用的语言,您可能不需要这样做:

(<Offering[^>]* templateid=ghi [^>]*>[^<]*<\/Offering>)

答案 2 :(得分:0)

正如您所说&#34;需要返回整个产品 节点 &#34;,可以说更简单,更安全,更易读的方式是DOM解析器。我已经在下面列出了如何在JavaScript和PHP中执行此操作的示例。

PHP

$doc = new DOMDocument();
@$doc->loadHTML($testStr); //Only needed if you're loading HTML like in the example which has repeated attributes and other things that could cause errors
$body = $doc->getElementsByTagName('body')->item(0);
$templateID = 'def';
$myNode = null;
foreach($body->childNodes as $node)
{
    if($node->nodeName=='offering')
    {
        if($node->attributes->getNamedItem('templateid')->nodeValue == $templateID)
        {
            $myNode = $node;
        }
    }
}
//$id = $myNode->attributes->getNamedItem('id')->nodeValue;
//$html = $doc->saveHTML($myNode)

的JavaScript

var testStr = document.getElementById('str_container').innerHTML;

var parser = new DOMParser();
var doc = parser.parseFromString(testStr,'text/html');
var templateID = 'def';
var myEl = null;
for(var i=0,c=doc.body.children.length;i<c;i++)
{
    if(doc.body.children[i].getAttribute('templateid')===templateID)
    {
        myEl = doc.body.children[i];
    }
}
//var id = myEl.id;
//var html = myEl.outerHTML;
console.log(myEl || 'not found');

JavaScript&gt; = IE8

var testStr = document.getElementById('str_container').innerHTML;

var parser = new DOMParser();
var doc = parser.parseFromString(testStr,'text/html');
var templateID = 'def';
var myEl = doc.body.querySelector('offering[templateid='+templateID+']');
//var id = myEl.id;
//var html = myEl.outerHTML;
console.log(myEl || 'not found');