删除顶级html标记之间的字符

时间:2018-02-10 11:23:49

标签: javascript jquery regex

总之,我正在寻找一种防弹解决方案,以便从HTML标记之间删除\ n来制作格式正确的HTML,而不是我收到的怪癖模式字符串。

更长的解释:我有一个包含HTML的字符串。我需要删除一些顶级标记之间的\ n字符串,但我不能从标记内容中删除\ n。

示例:

<p class='A'>AA A AAA</p>\n   \n  \n <p class='B'>BB BB \n BB\nBBB BB</p>

需要去的段落之间的\ n,但是必须保留与class = B的段落中的\ n \ n。这是一个简单的例子 - 在现实世界中没有预定义的类等,我只是得到具有不可预测内容的para标签。

我尝试了什么:

  • 简单的字符串替换已经结束了,因为当然它会击中必须保留的第二个para元素中的\ n。
  • 我已经找到了一个正则表达式解决方案,但是无法根据需要选择如何让它们有选择地工作。即使正则表达式很聪明,我认为它仍然会看到一个&#39; stream&#39;而不是结构&#39;
  • 我尝试将HTML加载到div中,然后撤回该div的HTML,希望它能够清理并删除#dc。 intertag \ n&n;但不是这样。

这是我目前使用jquery进行清理的解决方案。这只适用于我,因为我知道我不想在顶级标签之间保留文本。此外,由于任何文字都会丢失,因此无法通过递归方式来清理孙子或降低孙女。

&#13;
&#13;
var dIn =  $('#in');   // div to act as container to load subject html
var dOut = $('#out');  // div to act as container for cleaing op
var sOut='';           // string to accumulate output

var sIn = "<p class='A'>AA A\n AAA</p>\n   \n  \n <p class='B'>BB BB \n BB\nBBB BB<span>CC\nC</p>";
$('#t1').val(sIn);  // display starting string

dIn.html(sIn);  // load input string into a div element

dIn.children().each(function(){ // walk the children of the container
  dOut.append($(this));         // append each child of input container to output container
  sOut = sOut + dOut.html();     // and yank the output containers html to give the tag-only content
  dOut.html('');                // last clear the output container for the next pass 
})

// show the results
$('#t2').val(sOut);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="in"></div>


<div id="out"></div>

<div id="info">
  <textarea id='t1' rows='10' cols='40'>
  </textarea>
  <textarea id='t2' rows='10' cols='40'> 
  </textarea>
  
</div>
&#13;
&#13;
&#13;

注意:如果评论丢失,this post explains为什么正则表达式不起作用。道具为@melpomene

1 个答案:

答案 0 :(得分:1)

正则表达式在处理HTML文档时很棘手,因为元素可以相互嵌套,这使得您意识到导致复杂性的不同事物,让您陷入困境并提供令人讨厌的错误解决方法,这对我来说意味着头痛。 / p>

改为使用解析器。 DOM解析器实际上不是基于正则表达式的解析器。 DOM解决方案可以在第一级节点上运行,此时节点与RegEx解决方案不同。

DOM解决方案:

&#13;
&#13;
var html = `<p class='A'>AA A AAA</p>
   
  
 <p class='B' test required >BB BB 
 BB
BBB BB</p>`

var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
// Only immediate children of body
var query = doc.evaluate('//body/*/following-sibling::text()',
        doc,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );

for (let i = 0, length = query.snapshotLength; i < length; i++) {
    query.snapshotItem(i).textContent = query.snapshotItem(i).textContent.replace(/\n/g, "");
}

console.log(doc.body.innerHTML);
&#13;
&#13;
&#13;

RegEx解决方案(不是首选 - 它会分别查找关闭标记和打开标记,它们分别位于彼此旁边):

&#13;
&#13;
var html = `<p class='A'>AA A AAA</p>
   
  
 <p class='B' test required >BB BB
 BB
BBB BB</p>`

console.log(html.replace(/(<\/\w+>)([^<>]+)(<\w+(?:\s+[\w-]+(?:\s*=\s*(?:"[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*'))?)*\s*>)/g, function(match, $1, $2, $3) {
    return $1 + $2.replace(/\n/g, '') + $3;
}));
&#13;
&#13;
&#13;