正则表达式 php,将 ul li 替换为 div
Regex php, replace ul li by div
我有这个列表:
<ul>
<li class="myclass">blablabla 1</li>
<li class="myclass">blablabla 2</li>
<li class="myclass">blablabla 3</li>
</ul>
我想要一个正则表达式:
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
仅替换 <li>
有效,使用此正则表达式:
$pattern = '#<li class="newClass">(.+)</li>#';
$replacement = '<div class="newClass"></div>';
$texte = preg_replace($pattern, $replacement, $texte);
我也试过更换 <ul>
,但没用:
$pattern = '#<ul>(<li class="myclass">(.+)</li>)*</ul>#';
$replacement = '<div class="newClass"></div>';
$texte = preg_replace($pattern, $replacement, $texte);
怎么了?
您可以使用以下正则表达式在 <ol>...</ol>
标签之外执行所有 <li>
替换:
(?(DEFINE)(?<skip><ol>.*?<\/ol>))(?&skip)(*SKIP)(*FAIL)|\s*<li\s+class="myclass">(.*?)<\/li>\s*
(?(DEFINE) # We set up conditions
(?<skip><ol>.*?<\/ol>)) # What we skip
(?&skip)(*SKIP)(*FAIL) # Fail what we skip
| # Else, match this
\s*<li\s+class="myclass">(.*?)<\/li>\s*
替换字符串为:
<div class="newClass"></div>\n
然后,您只需删除 <ul>
和 </ul>
标签即可。
参见main regex demo here, and the sample program here。
<?php
$str = "<ul>\n <li class=\"myclass\">blablabla 1</li>\n <li class=\"myclass\">blablabla 2</li>\n <li class=\"myclass\">blablabla 3</li>\n</ul>\n<ol>\n <li class=\"myclass\">blablabla 1</li>\n <li class=\"myclass\">blablabla 2</li>\n <li class=\"myclass\">blablabla 3</li>\n</ol>\n<ul>\n <li class=\"myclass\">blablabla 1</li>\n <li class=\"myclass\">blablabla 2</li>\n <li class=\"myclass\">blablabla 3</li>\n</ul>";
$re = "/(?(DEFINE)(?<skip><ol>.*?<\/ol>))(?&skip)(*SKIP)(*FAIL)|\s*<li\s+class=\"myclass\">(.*?)<\/li>\s*/s";
$subst = "<div class=\"newClass\"></div>\n";
$result = preg_replace($re, $subst, $str);
echo preg_replace("/<\/?ul>/", "", $result);
?>
输出:
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
<ol>
<li class="myclass">blablabla 1</li>
<li class="myclass">blablabla 2</li>
<li class="myclass">blablabla 3</li>
</ol>
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
你的模式几乎是正确的。
$pattern = '#<ul>(<li class="myclass">(.+)</li>)*</ul>#';
不过,您的模式中存在多个缺陷。
<ul>
将假定您所有的 <li ...
都以 <ul>
开头,而 <li class="myclass">blablabla 2</li>
并非如此。因此,您必须将它与 ?
一起使用,最好在非捕获组中使用它。即 (?:<ul>)?
并且类似地在末尾 (?:<\/ul>)?
(注意 转义字符 )
您没有检查空格和换行符 before/after <li..
应该更改为 (\s*<li class="myclass">(.+)<\/li>\s*)
另外,(<li ...>...<\/li>)
后面不需要加*
您的模式的有效修改为 (?:<(?:ul|ol)>)?(\s*<li class="myclass">(.+)<\/li>\s*)(?:<\/(?:ul|ol)>)?
有关更多解释和探索,请参阅 demo。
我有这个列表:
<ul>
<li class="myclass">blablabla 1</li>
<li class="myclass">blablabla 2</li>
<li class="myclass">blablabla 3</li>
</ul>
我想要一个正则表达式:
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
仅替换 <li>
有效,使用此正则表达式:
$pattern = '#<li class="newClass">(.+)</li>#';
$replacement = '<div class="newClass"></div>';
$texte = preg_replace($pattern, $replacement, $texte);
我也试过更换 <ul>
,但没用:
$pattern = '#<ul>(<li class="myclass">(.+)</li>)*</ul>#';
$replacement = '<div class="newClass"></div>';
$texte = preg_replace($pattern, $replacement, $texte);
怎么了?
您可以使用以下正则表达式在 <ol>...</ol>
标签之外执行所有 <li>
替换:
(?(DEFINE)(?<skip><ol>.*?<\/ol>))(?&skip)(*SKIP)(*FAIL)|\s*<li\s+class="myclass">(.*?)<\/li>\s*
(?(DEFINE) # We set up conditions
(?<skip><ol>.*?<\/ol>)) # What we skip
(?&skip)(*SKIP)(*FAIL) # Fail what we skip
| # Else, match this
\s*<li\s+class="myclass">(.*?)<\/li>\s*
替换字符串为:
<div class="newClass"></div>\n
然后,您只需删除 <ul>
和 </ul>
标签即可。
参见main regex demo here, and the sample program here。
<?php
$str = "<ul>\n <li class=\"myclass\">blablabla 1</li>\n <li class=\"myclass\">blablabla 2</li>\n <li class=\"myclass\">blablabla 3</li>\n</ul>\n<ol>\n <li class=\"myclass\">blablabla 1</li>\n <li class=\"myclass\">blablabla 2</li>\n <li class=\"myclass\">blablabla 3</li>\n</ol>\n<ul>\n <li class=\"myclass\">blablabla 1</li>\n <li class=\"myclass\">blablabla 2</li>\n <li class=\"myclass\">blablabla 3</li>\n</ul>";
$re = "/(?(DEFINE)(?<skip><ol>.*?<\/ol>))(?&skip)(*SKIP)(*FAIL)|\s*<li\s+class=\"myclass\">(.*?)<\/li>\s*/s";
$subst = "<div class=\"newClass\"></div>\n";
$result = preg_replace($re, $subst, $str);
echo preg_replace("/<\/?ul>/", "", $result);
?>
输出:
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
<ol>
<li class="myclass">blablabla 1</li>
<li class="myclass">blablabla 2</li>
<li class="myclass">blablabla 3</li>
</ol>
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
你的模式几乎是正确的。
$pattern = '#<ul>(<li class="myclass">(.+)</li>)*</ul>#';
不过,您的模式中存在多个缺陷。
<ul>
将假定您所有的<li ...
都以<ul>
开头,而<li class="myclass">blablabla 2</li>
并非如此。因此,您必须将它与?
一起使用,最好在非捕获组中使用它。即(?:<ul>)?
并且类似地在末尾(?:<\/ul>)?
(注意 转义字符 )您没有检查空格和换行符 before/after
<li..
应该更改为(\s*<li class="myclass">(.+)<\/li>\s*)
另外,
(<li ...>...<\/li>)
后面不需要加
*
您的模式的有效修改为 (?:<(?:ul|ol)>)?(\s*<li class="myclass">(.+)<\/li>\s*)(?:<\/(?:ul|ol)>)?
有关更多解释和探索,请参阅 demo。