正则表达式错过了目标字符串的第一次出现
Regular expression missed first occurrence of target string
我在以下 html 代码中使用正则表达式来获取 text1 和 text2。这是我正在使用的:
/<div\s?class="right-col">[\s\n\S]*<a[\s\n]?[^>]*>@(.*)<\/a>/
但显然我错过了 text1,只得到了 text2(这里是 link to my problem)。
<div class="right-col">
<h1>
<a href="url-link-here" title="title-here">title1</a>
</h1>
<p>some text here</p>
<div class="some-class">
<div class="left">
<span><a href="url-link-here" class="breaking" target="_blank">some text here </a></span>
</div>
<div class="postmeta"><a href="url-link-here" >@text1</a> </div>
</div>
<div class="right-col">
<h1>
<a href="url-link-here" title="title-here">title2</a>
</h1>
<p>some text here</p>
<div class="some-class">
<div class="left">
<span><a href="url-link-here" class="breaking" target="_blank">some text here </a></span>
</div>
<div class="postmeta"><a href="url-link-here" >@text2</a> </div>
</div>
你们能告诉我我的正则表达式哪里出了问题吗?有没有更好的方法来捕获 title1, title2 和 text1, text2?
在这里使用正则表达式并不是最好的方法。这是不好的做法。您应该使用 DOM/XML 解析器来执行此操作。
我喜欢用PHP的DOMDocument class. Using XPath,我们可以快速找到你想要的元素
$dom = new DOMDocument;
$dom->loadHTML($html);
$xPath = new DOMXPath($dom);
$aTags = $xPath->query('//div[@class="some-class"]//a[starts-with(text(), "@")]');
foreach($aTags as $a){
echo $a->nodeValue;
}
这是正则表达式的一个相当普遍的问题,因为它们是贪婪的。 [\s\S]*(不需要 \n)匹配第一个 '<' 和 'a',因为它很贪心,所以它会匹配那些并继续。添加一个?让它不贪心并使用你的 link returns text1 和 text2.
简短的回答是将 [\s\n\S]* 替换为 [\s\S]*?但正如其他人所提到的,这可能不是正则表达式的好用法。
我在以下 html 代码中使用正则表达式来获取 text1 和 text2。这是我正在使用的:
/<div\s?class="right-col">[\s\n\S]*<a[\s\n]?[^>]*>@(.*)<\/a>/
但显然我错过了 text1,只得到了 text2(这里是 link to my problem)。
<div class="right-col">
<h1>
<a href="url-link-here" title="title-here">title1</a>
</h1>
<p>some text here</p>
<div class="some-class">
<div class="left">
<span><a href="url-link-here" class="breaking" target="_blank">some text here </a></span>
</div>
<div class="postmeta"><a href="url-link-here" >@text1</a> </div>
</div>
<div class="right-col">
<h1>
<a href="url-link-here" title="title-here">title2</a>
</h1>
<p>some text here</p>
<div class="some-class">
<div class="left">
<span><a href="url-link-here" class="breaking" target="_blank">some text here </a></span>
</div>
<div class="postmeta"><a href="url-link-here" >@text2</a> </div>
</div>
你们能告诉我我的正则表达式哪里出了问题吗?有没有更好的方法来捕获 title1, title2 和 text1, text2?
在这里使用正则表达式并不是最好的方法。这是不好的做法。您应该使用 DOM/XML 解析器来执行此操作。
我喜欢用PHP的DOMDocument class. Using XPath,我们可以快速找到你想要的元素
$dom = new DOMDocument;
$dom->loadHTML($html);
$xPath = new DOMXPath($dom);
$aTags = $xPath->query('//div[@class="some-class"]//a[starts-with(text(), "@")]');
foreach($aTags as $a){
echo $a->nodeValue;
}
这是正则表达式的一个相当普遍的问题,因为它们是贪婪的。 [\s\S]*(不需要 \n)匹配第一个 '<' 和 'a',因为它很贪心,所以它会匹配那些并继续。添加一个?让它不贪心并使用你的 link returns text1 和 text2.
简短的回答是将 [\s\n\S]* 替换为 [\s\S]*?但正如其他人所提到的,这可能不是正则表达式的好用法。