正则表达式:段落中的第一个<br/>

时间:2018-11-27 05:33:50

标签: php html regex laravel

如何捕获和删除段落中第一次出现的Win32Exception: Access is denied. System.Diagnostics.Process.Start_shell (System.Diagnostics.ProcessStartInfo startInfo, System.Diagnostics.Process process) System.Diagnostics.Process.Start_common (System.Diagnostics.ProcessStartInfo startInfo, System.Diagnostics.Process process) System.Diagnostics.Process.Start (System.Diagnostics.ProcessStartInfo startInfo) UnityEditor.Android.ADB.StartServer (UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit) UnityEditor.Android.ADB.Run (System.String[] command, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) UnityEditor.Android.AndroidDeploymentTargetsExtension.GetKnownTargets (IDeploymentTargetsMainThreadContext context, UnityEditor.ProgressHandler progressHandler) UnityEditor.DeploymentTargets.DeploymentTargetManager.GetKnownTargets () (at C:/buildslave/unity/build/Editor/Mono/DeploymentTargets/DeploymentTargetManager.cs:50) UnityEditor.Android.AndroidBuildWindowExtension+<SpawnFetchTargetsThread>c__AnonStorey0.<>m__0 () UnityEditor.Android.<SpawnFetchTargetsThread>c__AnonStorey0:<>m__0() 标签。

<br/>

成为:

<p><br/>Hello World</p>

但重要的是,以下内容保持不变:

<p>Hello World</p>
  

从包含文本的段落中删除前导<p><br/></p> 标签


到目前为止我所拥有的:

<br>

尽管这捕获了preg_replace('/(<p>\s*<br *\/?>(.*?)<\/p>)+/si', '<p>$2</p>', $html); 个实例...

3 个答案:

答案 0 :(得分:2)

这是使用DOMDocumentDOMXPath类内置的PHP来实现的方式:

$html = "<div><p><br/>Hello World</p><p><br/></p><p> <br> </p></div>";
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
// find <br> within a <p> that has text content
$breaks = $xpath->query("//p[normalize-space()!='']/br");
$breaks = $xpath->query("//p[text()!='']/br");
// and remove them
foreach ($breaks as $br) {
    $br->parentNode->removeChild($br);
}
echo $doc->saveHTML();

请注意,有两行将值分配给$breaks。您应该使用一个满足您要求的元素:第一个元素只会从<br><p>之间具有非空白字符的元素中去除</p>,而第二个元素也会从中去除它们<p>个元素仅包含空格。可以在此demo中看到不同的效果。

答案 1 :(得分:0)

如果还有更多规则,我们可以在preg_replace中传递数组。在我的解决方案中,pattern中的第一个元素将查找带有文本的<br />。第二个将只查找没有文本的<br />。另外,此搜索也是从字符串(/^..的开头开始的。

preg_replace(['/^(<p>\s*(<br *\/?>)([a-zA-Z0-9 ]+)<\/p>)+/si', '/^(<p>\s*(<br *\/?>)<\/p>)+/si'], ['<p>$3</p>', '$0'], $html); 

答案 2 :(得分:0)

不建议使用正则表达式解析html。但是,为了快速而临时地工作,您可以使用此正则表达式捕获一个换行符<br/>,该换行符之前带有<p>标签和一些文本,并进行预见性处理,因此不应立即关闭{ {1}}标签。

</p>

并将捕获的<p>.*?\K<br\/>(?!<\/p>) 替换为空字符串,从而将其删除。

说明:

  • <br/>->匹配段落标记,然后以非贪婪方式匹配任何字符
  • <p>.*?->重置所有匹配项,因为我们不打算替换
  • \K->匹配一个换行符,该符不是紧随其后的段落标记,它将被空字符串替换。

Demo

以下是示例php代码,

<br\/>(?!<\/p>)

输出以下输出,

$html = '<p><br/>Hello World</p>';
$html = preg_replace('/<p>.*?\K<br\/>(?!<\/p>)/si', '', $html);
echo $html. "\n";


$html = '<p><br/></p>';
$html = preg_replace('/<p>.*?\K<br\/>(?!<\/p>)/si', '', $html);
echo $html. "\n";