【问题标题】:How can I replace spaces inside of HTML tags without removing the tags如何在不删除标签的情况下替换 HTML 标签内的空格
【发布时间】:2021-08-16 09:38:31
【问题描述】:

假设我有这个字符串:

$string = '<p > ¡Esto es una prueba! < /p > <p> <strong > Prueba 123 </strong> </p> <p> <strong> < a href="https://matricom.net"> MATRICOM < / a> </ strong> </p> <p> <strong > Todas las pruebas aquí ... </strong > < /p>'

我想做的是使用 PHP 修复 HTML 标签(由于空格,它们格式错误)。我尝试了几种不同的正则表达式,我在网上找到了这样的表达式:

$html = trim(preg_replace('/<\s+>/', '<>', $text));

和:

$html = preg_replace('/<(.+?)(?:»| |″)(.+?)>/', '<\1\2>', $text);

我正在尝试获取这样的字符串输出(在 HTML 标记的前面部分和结尾部分删除了空格):

'<p> ¡Esto es una prueba! </p> <p> <strong> Prueba 123 </strong> </p> <p> <strong> <a href="https://matricom.net"> MATRICOM </a> </strong> </p> <p> <strong> Todas las pruebas aquí ... </strong> </p>'

背景故事:Google 翻译倾向于在翻译结果中添加影响 HTML 结构的随机空格。只是寻找一种快速清理标签的方法。我已经搜索了两天如何做到这一点,似乎找不到任何适合我正在寻找的东西。

【问题讨论】:

  • 您还尝试了什么?使用简单的字符串替换(从 &lt; 到 &lt;)或使用 DomDocument 是否有帮助?
  • 您好,下面的答案有帮助吗?

标签: php html regex


【解决方案1】:

你可以使用

preg_replace('~<\K\s*(?:(/)\s+)?|\s+(?=>)~u', '$1', $string)

查看regex demo 和PHP demo:

$string = '<p > ¡Esto es una prueba! < /p > <p> <strong > Prueba 123 </strong> </p> <p> <strong> < a href="https://matricom.net"> MATRICOM < / a> </ strong> </p> <p> <strong > Todas las pruebas aquí ... </strong > < /p>';

echo preg_replace('~<\K\s*(?:(/)\s+)?|\s+(?=>)~u', '$1', $string);
// => <p> ¡Esto es una prueba! </p> <p> <strong> Prueba 123 </strong> </p> <p> <strong> <a href="https://matricom.net"> MATRICOM </a> </strong> </p> <p> <strong> Todas las pruebas aquí ... </strong> </p>

正则表达式详细信息:

  • &lt;\K\s*(?:(/)\s+)? - &lt; 被匹配,然后从与 \K 的匹配中删除,然后匹配零个或多个空格,然后是可选的 / 序列(捕获到组 1)和一个或多个空格匹配
  • | - 或
  • \s+(?=&gt;) - 一个或多个空格,紧跟在 &gt; 之后

替换为 Group 1 值(当可选组匹配时,它是空字符串或/)。

【讨论】:

  • 这种模式在功能上与&lt; *(\/*) *(.+?) *&gt; 有什么不同吗,就像我的回答一样。我在尝试学习。我的意思是它们都产生相同的输出,所以哪个是更好的选择。 \s 也会匹配制表符和换行符。
  • @endeavour Yours 是一个有趣的解决方案。你可以像这样增强它:1)用\s替换空格以匹配任何空格。请注意我使用的 u 标志,它使 \s 匹配 any Unicode 空白,2) 将 . 替换为 [^&gt;] 以仅匹配单个标签。
【解决方案2】:

这就是我想出的。适用于您的字符串

< *(\/*) *(.+?) *>

<     Matches a < char
 *    Matches zero or more spaces. There is a ' ' (space) before *
(\/*) Matches zero or more / () indicates capturing group 1
 *    Matches zero or more. Do notice the ' ' before *
(     Start of capturing group 2
.+    Matches any character except a line break
?     Lazy Matching
)     End of capturing group 2
 *   Matches zero or more spaces. Again a ' ' before *
>     Matches a > char

然后像

$cleaned = preg_replace('/< *(\/*) *(.+?) *>/', '<\1\2>', $html);
echo $cleaned;

# input string
# '< p > ¡Esto es una prueba! < /p > <p> <strong > Prueba 123 </strong> </p> <p> <strong> < a href="https://matricom.net"> MATRICOM < / a> </ strong> </p> <p> <strong > Todas las pruebas aquí </strong > < /p>';

# Cleaned string
# <p> ¡Esto es una prueba! </p> <p> <strong> Prueba 123 </strong> </p> <p> <strong> <a href="https://matricom.net"> MATRICOM </a> </strong> </p> <p> <strong> Todas las pruebas aquí </strong> </p>

这将从这些格式中删除空格

&lt; div &gt; &lt;/ div &gt; &lt; / div &gt; &lt; div class="myclass" &gt;

但它不会删除属性中的空格。所以这 &lt; div class = " myclass " &gt; 将转换为 &lt;div class = " myclass "&gt;。但是属性中的空格是允许的(尽管不推荐)

如果我遗漏了一个案例,请告诉我,我会尝试合并。

【讨论】:

    【解决方案3】:

    我不推荐这种方法。虽然正则表达式很棒,但您可能会错过一些情况,因为谷歌翻译似乎在随机位置添加了随机空格。你不可能在所有情况下都是可靠的。

    我建议发送纯文本或使用 V2 翻译 API 的 format=html 参数让 Google 翻译正确解释 HTML 标记。

    https://cloud.google.com/translate/docs/reference/rest/v2/translate#query-parameters

    如果你不能使用上面官方的方法,在发送到谷歌翻译之前,根据标签分割文本,这样你可以有一个更清晰的输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多