1

这是我的正则表达式:

$pattern_new="/<td>(\n|\s)*?(<span(\n|\s|.)*?<\/strong>(\n|\s)*?\$(?<price>([0-9.]*)).*?)\$(.*?)(\n|\s)*?</";

这是我必须进行匹配的示例模式:

<td><strong>.zx</strong></td><td><span class="offer"><strong>xscre:<br></strong>$299 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&ea;s $399</td><td>zxcddcdcdcdc</td></tr><tr class="dark"><td><strong>.aa.rr</strong></td><td><span class="offer"><strong>xscre:<br></strong>$99 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&eae;s $199</td><td>xxxx</td></tr><tr class="bar"><td colspan="3"></td></tr><tr class="bright"><td><strong>.vfd</strong></td><td><span class="offer"><strong>xscre:<br></strong>$99 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>du&ee;s $199</td><td>xxxxxxxx</td></tr><tr class="dark"><td><strong>.qwe</strong></td><td><span class="offer"><strong>xxx<br></strong>$99 xxxc;o<span class="fineprint_number">2</span>

这是我在 PHP 中所做的

$pattern_new="/<td>(\n|\s)*?(<span(\n|\s|.)*?<\/strong>(\n|\s)*?\$(<price>)*([0-9.]*).*?)\$(.*?)(\n|\s)*?</";
$source = file_get_contents("https://www.abc.com/sources/data.txt");
preg_match_all($pattern_new, $source, $match_newprice, PREG_PATTERN_ORDER);
echo$source;
print_r($match_newprice);

正在$match_newprice返回一个空数组。

当我使用像myregextestersolmetra.com这样的正则表达式测试器时,我得到了一个完美的匹配,没有任何问题,但是当我使用 phppreg_match_all进行匹配时,它返回一个空数组。我增加了 pcre.backtrack_limit 但它仍然是同样的问题。我似乎不明白这个问题。任何帮助将非常感激。

4

3 回答 3

2

我假设您正在尝试创建一个非捕获组,<price...但您错过了:. 或者你应该去掉问号。如果该price组是可选的,请尝试下面的正则表达式。您应该使用以下网站来帮助您使用正则表达式。我觉得它非常有帮助。

<td>(\n|\s)*?(<span(\n|\s|.)*?<\/strong>(\n|\s)*?\$(<price>)*([0-9.]*).*?)\$(.*?)(\n|\s)*?<

正则表达式图片

在 Debuggex 上实时编辑

在上面的示例中,您的第一个匹配项将具有以下捕获:

0: "<td><span class="offer"><strong>xscre:<br></strong>$299 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&ea;s $399<"
1: ""
2: "<span class="offer"><strong>xscre:<br></strong>$299 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&ea;s "
3: ">"
4: ""
5: ""
6: "299"
7: "399"
8: ""

这是你想要的?

于 2013-06-20T20:22:38.247 回答
1

另一个与 PHP 相关的问题:

<?php
echo "\$".PHP_EOL;
echo '\$'.PHP_EOL;

结果:

$
\$

...就像在双引号字符串中一样,$预计将表示变量的开始,如果您的意思是裸露的,则需要转义$/x在您的正则表达式周围加上单引号,它可能会很好(虽然没有详细查看,如果您需要在半年后调试它,您可能想要使用该选项并添加一些格式化空格/注释)。

于 2013-06-20T22:14:16.630 回答
1

这样做的好方法:

$oProductsHTML = new DOMDocument();
@$oProductsHTML->loadHTML($sHtml);

$oSpanNodes = $oProductsHTML->getElementsByTagName('span');

foreach ($oSpanNodes as $oSpanNode) {
    if (preg_match('~\boffer\b~', $oSpanNode->getAttribute('class')) &&
        preg_match('~\$\K\d++~', $oSpanNode->nodeValue, $aMatch) )
    {
        $sPrice = $aMatch[0];
        echo '<br/>' . $sPrice;
    }
}

$sHtml代表你的字符串。

我相信你可以用 XPath 让它更短。

坏方法:

$sPattern = '~<span class="offer\b(?>[^>]++|>(?!\$))+>\$\K\d++~';
preg_match_all($sPattern, $sHtml, $aMatches);

print_r ($aMatches[0]);

注意:\d++可以替换\d++(?>\.\d++)?为允许十进制数。

于 2013-06-20T22:17:09.793 回答