使用 PHP preg_replace将可能嵌套的 HTML 转换UL
为 CSV(4 个字段)我遇到了障碍。以下行处理嵌套列表的一部分,这些列表未更改(删除的换行符除外)到从最顶层 UL 创建的字段之一中:
$idx_string = preg_replace("|(<li>.*?)\n+(<ul>)\n+(.*?</li></ul></li>)|si","$1$2$3", $idx_string);
现在在一些没有嵌套列表的大列表上(检查在转换时没有这样的东西<ul>
),由于 backtrack_limit_error 而失败。因此,虽然我知道如何克服它,但我无法弄清楚什么都不匹配会触发回溯限制。根据我的发现,preg_replace 返回新字符串或未更改的旧字符串(错误时为 NULL/FALSE 除外)。那么 backtrack 是如何进入这里的呢?
列表项如下所示:
<li><a href="9848.php">Algeria - Italy.</a></li>
<li>Go sailing<br>
<a href="11434.php">Anglesey / Wight / Guernsey / Jersey</a></li>
<li><a href="11367.php">d'Anjou et du Saumurois, Carte des Gouvernements</a><br>
Check out the old places!</li>
CSV 如下所示:
|9848.php|Algeria - Italy.|
Go sailing|11434.php|Anglesey - Anglesey / Wight / Guernsey / Jersey|
|11367.php|d'Anjou et du Saumurois, Carte des Gouvernements|Check out the old places!
因此,实际上所有标签都被剥离,其余标签分为 4 个字段。奇数嵌套列表按原样填充到第三个字段中,即带有<ul>
&<li>
标记,仅去除换行符。
这是一些用作回退机制的旧 PHP 4 代码。DOMDocument
可能是更好的通用方法,但我不想在这方面投入太多时间,而且列表的格式非常严格和简单。
加起来
再次考虑 Jerry 的注释查看代码,很明显第一组如何让(<li>.*?)
PHP 从<li>
文件顶部的第一个右侧开始,并咀嚼整个文件以搜索 a <ul>
,全部进入一个回溯空间。
将语句包含在if (stripos($idx_string, '<ul')) { ... }
块中可以减少触发错误的机会,将 pcre.backtrack_limit 提高到 1000000 也是如此,无论如何,这是 PHP 5.3.7 的默认值,但由于某种原因没有更新到这里。记录了这么多。