如果找不到所需的属性,Regex将匹配下一个属性.如何限制它


Regex matches next attribute if the desired one is not found. How to restrict it?

使用regex和PHP,我试图获得标题属性的内容,如下所示。

preg_match('/<abbr class="dtstart" title="([^"]*)"/i', $file_string, $starts);
$starts_out = $starts[1];
preg_match('/<abbr class="dtend" title="([^"]*)"/i', $file_string, $ends);
$ends_out = $ends[1];

这是我想要得到的代码的确切部分,我得到了正确的数据。

<div id="eventDetailInfo">
    <h2>When</h2>
    <div class="p">
        <div>From:
            <abbr class="dtstart" title="2012-08-24T17:00:00">Friday, August 24th, 2012</abbr></div>
        <div>Until:
            <abbr class="dtend" title="2012-08-26">Saturday, August 25th, 2012</abbr></div>
    </div>
</div>

然而,因为有时在某些文章中没有Until,所以regex与剩余代码中的第一个匹配(这是相关文章)。

我的问题是,如果没有,我如何限制正则表达式仅与上面的匹配

<div>Until:
                <abbr class="dtend" title="2012-08-26">Saturday, August 25th, 2012</abbr></div>

是否找到,以保持空白?

这是页面的其余代码,不幸的是正则表达式与之匹配

<div class="evdate">
    <em>When:</em>
    <abbr class="dtstart" title="2012-07-03T21:00:00">July 3rd</abbr>
    to
    <abbr class="dtend" title="2012-07-13">July 12th</abbr>*
</div>
<div class="evtime"><em>Time:
    </em>
    21:00
</div>
</div>

虽然我同意其他人关于不使用正则表达式来匹配HTML的观点,但就我个人而言,如果您需要确切地知道可以得到什么,正则表达式会非常有用。除非您抓取不同来源的负载,否则您通常不需要DOM框架提供的一致性。

任何人,考虑到你的问题,我认为DOM不一定会帮助你,你仍然需要设计它,只从某些类/模式中学习。这样做的方法是扩展regex,使其不仅匹配您想要的内容,还匹配包含的内容,因此您需要在模式中包含一些独特的内容,这样它就不会与相关文章匹配。(与您需要对DOM进行的操作相同,只是稍微简单一点!)

虽然我已经向您展示了如何使用快速正则表达式来实现这一点,但我明确建议您不要在这类事情上使用正则表达式。正如你亲眼所见,它很快就会失控。

正如其他人所指出的(这里和那里),您应该为此使用HTML解析器。


我建议您使用SimpleHTMLDOM,因为它很容易使用,而且它们的文档也很好。