英文:
search and replace but only if between two markers php regex
问题
I want to replace the <br>
tags with a space in a string containing html, but only if the tag is within a <div class="nobr">
..... </div>
sequence. I presume the best way is to use preg_replace but I'm having difficulty finding the regex expression to use for the pattern... (there will be multiple line break tags and more than one "nobr" div)
e.g Simple example - From this:
keep this<br>
line break<div class="nobr">
but replace this linebreak<br>
with a space</div>
To become:
keep this<br>
line break<div class="nobr">
but replace this linebreak with a space</div>
英文:
I want to replace the <br>
tags with a space in a string containing html, but only if the tag is within a <div class="nobr">
..... </div>
sequence. I presume the best way is to use preg_replace but I'm having difficulty finding the regex expression to use for the pattern... (there will be multiple line break tags and more than one "nobr" div)
e.g Simple example - From this:
keep this<br>
line break<div class="nobr">
but replace this linebreak<br>
with a space</div>
To become:
keep this<br>
line break<div class="nobr">
but replace this linebreak with a space</div>
答案1
得分: 1
你可以首先匹配 nobr
元素,然后使用 preg_replace_callback 和回调函数来替换 <br>
。
$pattern = '/<div class="nobr">(.*?)<\/div>/s';
// 此正则表达式模式将匹配以 "<div class="nobr">" 开头,并以 "</div>" 结尾的字符串,并捕获其中的所有字符,包括换行符(使用 "s" 标志)。
$string = preg_replace_callback($pattern, function ($matches) {
return str_replace('<br>', ' ', $matches[0]);
// preg_replace_callback 函数将在每个匹配的 "nobr" div 中用空格替换所有 "<br>" 标签。
}, $string);
这仅在没有嵌套的 div 时有效,因为关闭标签会匹配嵌套的 div 关闭标签。如果有嵌套的 div,你需要使用 DOM 解析器:
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
$nobr_divs = $xpath->query("//div[contains(concat(' ', normalize-space(@class), ' '), ' nobr ')]");
foreach ($nobr_divs as $nobr_div) {
$br_tags = $nobr_div->getElementsByTagName('br');
foreach ($br_tags as $br_tag) {
$text = $doc->createTextNode(' ');
$nobr_div->replaceChild($text, $br_tag);
}
}
$new_html = $doc->saveHTML();
echo $new_html;
英文:
You could first match the nobr
elements and use a callback function with preg_replace_callback to replace the <br>
.
$pattern = '/<div class="nobr">(.*?)<\/div>/s';
// This regex pattern will match any string that starts with
// "<div class="nobr">" and ends with "</div>", and capture
// all characters in between, including line breaks (using the "s" flag).
$string = preg_replace_callback($pattern, function ($matches) {
return str_replace('<br>', ' ', $matches[0]);
// The preg_replace_callback function will replace all
// "<br>" tags with spaces within each matched "nobr" div.
}, $string);
This would only work if you don't have nested divs, since the closing tag would match the nested div closing tag. If that's the case you need to use a DOM parser:
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
$nobr_divs = $xpath->query("//div[contains(concat(' ', normalize-space(@class), ' '), ' nobr ')]");
foreach ($nobr_divs as $nobr_div) {
$br_tags = $nobr_div->getElementsByTagName('br');
foreach ($br_tags as $br_tag) {
$text = $doc->createTextNode(' ');
$nobr_div->replaceChild($text, $br_tag);
}
}
$new_html = $doc->saveHTML();
echo $new_html;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论