簡體   English   中英

用於刪除無效 HTML 標記之間空格的正則表達式 - 即“</b>”應為“”

[英]Regex to remove spaces between invalid HTML tags - i.e. "< / b >" should be "</b>"

我有一些 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 > ,但我正在努力解決其余問題

例如,我可以采用嚴厲的方法,但這也會破壞標簽文本部分的代碼,而不是標簽名稱本身

沒有合理的方法可以將文檔保存為與您發布的內容一樣損壞,但假設您將文本中的>和類似字符替換為它們的相關實體,例如: &gt; ,您可以將要接受的文檔按摩到適當的庫中,例如DomDocument ,它將處理其余部分。

$input = <<<_E_
< div class='test' >1 &gt; 0 is < b >true</ b> and apples &gt;&gt;&gt; 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 &gt; 0 is <b>true</b> and apples &gt;&gt;&gt; bananas</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);

您可以將幾個.replace()與 RegEx 和自定義替換回調一起使用:

 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 的細分:

  1. s.replace(/<.*?>/g, /* arrow function */)

這將為<>括號內的所有內容運行長箭頭函數作為自定義替換函數。 這樣,替換只會影響標簽內部。 箭頭函數接受一個參數m ,即原始文本,並返回替換它的文本。

  1. m.replaceAll(' ', '')

刪除字符串中的所有空格。 這也將刪除標簽名稱和屬性之間的空格,因此我們需要第 3 步。

  1. .replace(m.match(/[a-zA-Z]+/)[0], tagName => tagName + ' ')

這采用步驟 2 的結果並在每個標簽名稱后添加一個空格。 m.match(/[a-zA-Z]+/)[0]將是標簽名稱,因為m仍然包含步驟 2 之前的原始文本。

  1. .replace(' >', '>')

這將得到沒有屬性或標簽是結束標簽的最后一個邊緣情況,因此第 3 步實際上添加了一個不必要的空格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM