繁体   English   中英

使用 RegEx 删除空标签

[英]Remove empty tags using RegEx

我想删除空标签,例如<label></label><font> </font>以便:

<label></label><form></form>
<p>This is <span style="color: red;">red</span> 
<i>italic</i>
</p>

将被清理为:

<p>This is <span style="color: red;">red</span> 
<i>italic</i>
</p>

我在javascript中有这个RegEx,但它删除了空标签,但它也删除了这个: "<i>italic</i></p>"

str=str.replace(/<[\S]+><\/[\S]+>/gim, "");

我缺少什么?

正则表达式不适用于 HTML。 如果您使用 JavaScript 无论如何我会被鼓励使用 jQuery DOM 处理。

就像是:

$('*:empty').remove();

或者:

$("*").filter(function() 
{ 
     return $.trim($(this).html()).length > 0; 
}).remove();

您的字符类有“非空格”,这意味着“ <i>italic</i></p> ”将匹配。 正则表达式的前半部分将匹配“ <(i>italic</i)> ”和后半部分“ </(p)> ”。 (我使用括号来显示每个[\\S]+匹配的内容。)

改变这个:

/<[\S]+><\/[\S]+>/

对此:

/<[^/>][^>]*><\/[^>]+>/

总体而言,您确实应该使用合适的 HTML 处理器,但是如果您正在处理 HTML 汤,这应该就足够了:)

正则表达式的所有答案都只是验证

<label></label>

但在这种情况下

<label> </label>
<label>    </label>
<label>
</label> 

试试这个模式来获得以上所有内容

<[^/>]+>[ \n\r\t]*</[^>]+>

您需要/<[\\S]+?><\\/[\\S]+?>/ -- 区别在于? + s 之后的 s,匹配“尽可能少”(又名“非贪婪匹配”)非空格字符(尽管 1 个或更多),而不是匹配“尽可能多”(又名“贪婪”)的裸+ s比赛”)。

完全避开正则表达式,为对方的回答建议,也是一个很好的主意,但我想指出的重要贪婪与非贪婪的区别,这将有助于你在一个巨大的各种情况下的正则表达式必要的。

我喜欢 MattMitchell 的 jQuery 解决方案,但这是使用原生 JavaScript 的另一种选择。

function CleanChildren(elem)
{
    var children = elem.childNodes;
    var len = elem.childNodes.length;

    for (var i = 0; i < len; i++)
    {
        var child = children[i];

        if(child.hasChildNodes())
            CleanChildren(child);
        else
            elem.removeChildNode(child);

    }
}

这是一个现代原生 JavaScript 解决方案; 这实际上与 2010 年的 jQuery 非常相似。我根据我正在从事的项目的答案改编了它,并认为我会在这里分享。

document.querySelectorAll("*:empty").forEach((x)=>{x.remove()});
  • document.querySelectorAll返回一个NodeList 它本质上是一个所有 DOM 节点的数组,这些节点与作为参数提供给它的 CSS 选择器相匹配。

    • *:empty是一个选择器,它选择所有为空的元素( *表示“任何元素”)(这就是:empty意思)。

      这将选择整个文档中的任何空元素,如果您只想从页面的某个部分(即仅某些div元素中的那些)中删除任何空元素; 您可以向该元素添加一个 id ,然后使用选择器#id *:empty ,这意味着元素中 id 为id任何空元素。

      这几乎肯定是您想要的。 从技术上讲,一些重要的标签(例如<meta>标签、 <br>标签、 <img>标签等)是“空的”; 所以不指定范围,你最终会删除一些你可能关心的标签。

  • forEach遍历结果NodeList中的每个元素,并在其上运行匿名函数(x)=>{x.remove()} x是列表中的当前元素,对它调用.remove()会从 DOM 中删除该元素。

希望这有助于某人。 看到 JavaScript 在短短 8 年中取得了如此大的进步,真是太神奇了; 从几乎总是需要一个库来以简洁的方式编写这样复杂的东西,到能够在本机上做到这一点。

编辑

所以,上面详述的方法在大多数情况下都可以正常工作,但它有两个问题:

  • <div> </div>元素不被视为:empty (不是中间的空格)。 CSS Level 4 选择器通过引入:blank选择器来解决这个问题(它就像空的,除了忽略空格),但目前只有 Firefox 支持它(以供应商前缀形式)。
  • 自闭合标签被:empty捕获 - :blank也是如此。

我编写了一个稍大的函数来处理这两个用例:

document.querySelectorAll("*").forEach((x)=>{
    let tagName = "</" + x.tagName + ">";
    if (x.outerHTML.slice(tagName.length).toUpperCase() == tagName
        && /[^\s]/.test(x.innerHTML)) {
        x.remove();
    }
});

我们遍历页面上的每个元素。 我们获取该元素的标签名称(例如,如果该元素是一个 div,这将是DIV ,并使用它来构造一个结束标签 - 例如</DIV>

该标签有 6 个字符长。 我们检查元素 HTML 的大写最后 6 个字符是否匹配。 如果是,我们继续。 如果没有,则该元素没有结束标记,因此必须是自闭合的。 这比列表更可取,因为这意味着如果新的自关闭标签被添加到规范中,您不必更新任何内容。

然后,我们检查元素的内容是否包含任何空格。 /[^\\s]/是一个正则表达式。 []是 RegEx 中的一个集合,将匹配出现在其中的任何字符。 如果^是第一个元素,则集合变为否定- 它将匹配不在集合中的任何元素。 \\s表示空格 - 制表符、空格、换行符。 所以[^\\s]说的是“任何不是空白的字符”。

与之匹配,如果标签不是自闭合的,并且其内容包含非空白字符,那么我们将其删除。


当然,这比之前的 one-liner 更大,更不优雅。 但它基本上应该适用于每种情况。

这是贪婪正则表达式的问题。 尝试这个:

str=str.replace(/<[\\^>]+><\\/[\\S]+>/gim, "");

或者

str=str.replace(/<[\\S]+?><\\/[\\S]+>/gim, "");

在您的正则表达式中, <[\\S]+?>匹配<i>italic</i>并且<\\/[\\S]+>匹配</p>

你可以用这个text = text.replace(/<[^/>][^>] >\\s </[^>]+>/gim, "");

在代码笔上找到了这个:jQuery,但可以完成这项工作

$('element').each(function() {
  if ($(this).text() === '') {
    $(this).remove();
  }
});

您需要更改元素以指向要删除空标签的位置。 不要指向文档,因为它会导致我在 Toastrackenigma 给出答案

使用cheerio will删除空标签并删除图像:

  $('*')
    .filter(function(index, el) {
      return (
        $(el)
          .text()
          .trim().length === 0
      )
    })
    .remove()

使用cheerio删除空标签,但也保留图像:

  $('*')
    .filter(function(index, el) {
      return (
        el.tagName !== 'img' &&
        $(el).find(`img`).length === 0 &&
        $(el)
          .text()
          .trim().length === 0
      )
    })
    .remove()
<([^>]+)\s*>\s*<\/\1\s*>
<div>asdf</div>
<div></div> -- will match only this
<div></notdiv>
-- and this
<div  >  
    </div   >

试试自己https://regexr.com/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM