我有一些HTML标记中的空格都被破坏了,我想让它再次有效-例如:
< div class='test' >1 > 0 is < b >true</ b> and apples >>> bananas< / div >
应该转换为有效的HTML,当呈现时,它将预期产生:
<div class='test'>1 > 0 is <b>true</b> and apples >>> bananas</div>
文本中任何前面/后面有空格的>
或<
都应保持不变——例如,1 > 0
应保持不变,而不是压缩为1>0
我意识到这可能需要几个正则表达式,这是很好的
我有一些东西:
<s?/s*
将部分修复</ b>< / div >
到</b></div >
,但我正在与其他作斗争
例如,我可以采用严厉的方法,但这也会破坏标签文本部分中的代码,而不是标签名称本身
此正则表达式也适用:
它将HTML标记中的有效部分捕获为四个部分,并用它替换其余部分(空格)。
Regex101演示
/(<)s*(/?)s*([^<>]*S)s*(>)/g
(<)
-捕获起始角括号(第1节)s*
-匹配任何空格(/?)
-捕获可选的后斜杠(第2节)s*
-匹配后斜杠后的任何空格([^<>]*S)
-捕获标签内的内容,不带尾随空格(第3节)s*
-匹配内容后和右尖括号前的空格(>)
-捕捉闭合角括号(第4节)
const reg = /(<)s*(/?)s*([^<>]*S)s*(>)/g
const str = "< div class='test' >1 > 0 is < b >true< / b > and apples >>> bananas< / div >"
const newStr = str.replace(reg, "$1$2$3$4");
console.log(newStr);
没有合理的方法可以保存像您发布的那样损坏的文档,但假设您将文本中的>
和类似字符替换为它们的相关实体,例如:>
,您可以将文档放入适当的库中,如DomDocument,该库将处理其余部分。
$input = <<<_E_
< div class='test' >1 > 0 is < b >true</ b> and apples >>> bananas< / div >
_E_;
$input = preg_replace([ '#<s+#', '#</s+#' ], [ '<', '</' ], $input);
$d = new DomDocument();
$d->loadHTML($input, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
var_dump($d->saveHTML());
输出:
string(80) "<div class="test">1 > 0 is <b>true</b> and apples >>> bananas</div>"
您可以使用几个带有RegEx和自定义替换回调的.replace()
:
let s = `< div class='test' >1 > 0 is < b >true</ b> and apples >>> bananas< / div >`;
s = s.replace(/<.*?>/g, m => m.replaceAll(' ', '').replace(m.match(/[a-zA-Z]+/)[0], tagName => tagName + ' ').replace(' >', '>')
);
console.log(s);
以下是RegEx:的明细
s.replace(/<.*?>/g, /* arrow function */)
这将运行长箭头函数,作为<
和>
括号内所有内容的自定义替换器函数。这样,替换只会影响标签内部。箭头函数接受一个参数m
,它是原始文本,并返回文本以将其替换为。
m.replaceAll(' ', '')
删除字符串中的所有空格。这也将删除标记名称和属性之间的空格,因此我们需要步骤3。
.replace(m.match(/[a-zA-Z]+/)[0], tagName => tagName + ' ')
这将获得步骤2的结果,并在每个标记名称后添加一个空格。m.match(/[a-zA-Z]+/)[0]
将是标签名称,因为m
仍然包含步骤2之前的原始文本。
.replace(' >', '>')
这将得到最后一个边缘情况,其中没有属性或标记是结束标记,因此步骤3实际上添加了不必要的空间。