只匹配<br>如果在</p>但不能直接跟在</p>后面
Only match <br> if directly before </p> but not directly after </p>
我正在尝试使用正则表达式来清理在我自己的html5 RTE中生成的一些代码。搜索周围,我看到很多人说正则表达式不应该用来解析html…但我正在用JavaScript做这个客户端。除了正则表达式,我还有其他选择吗?
我一直在尝试使用lookbehind(刚刚发现他们),但他们似乎不与JavaScript工作。我想做的是删除所有的
在
s的最后,但不是段落中唯一的元素,如
<p>Blah<br><br><br></p> becomes <p>Blah</p>
<p><br></p> stays the same.
目前只有
html = html.replace(/(?:<br's?'/?>)+(<'/p>)/g, '$1');
将删除段落末尾的所有
,无论有多少。
我想要像
html = html.replace(/(?<!<p>)(?:<br's?'/?>)+(<'/p>)/g, '$1');
编辑:我使用一个可满足的div来创建一个非常简单的RTE,每次用户想要改变一些文本时动态创建。基本上只是清除多余的span, br和p标签,等等。
使用DOM解析器
的想法是保留所有连续的<br>
元素。每次出现非空文本元素或任何其他元素时清除数组。
如果在循环结束时存在<br>
列表,则删除它们。这些是末尾的<br>
元素。
var $pp = document.getElementsByTagName("p");
for(var i = 0, $p = $pp[0], $br = [], alone = true; i < $pp.length; i = i + 1, $p = $pp[i], $br = [], alone = true){
for(var j = 0, $child = $p.childNodes[0]; j < $p.childNodes.length; j = j + 1, $child = $p.childNodes[j]){
if(($child.tagName !== "BR") && ($child.textContent.trim() !== "")){
alone = false;
$br = [];
} else {
$br.push($child);
}
}
for(var j = 0; j < $br.length - alone; j = j + 1){
$p.removeChild($br[j]);
}
}
例如,<p>Foo<br><br><br></p>
<p>Foo<br>Bar<br><br></p>
<p><br></p>
是
<p>Foo</p>
<p>Foo<br>Bar</p>
<p><br></p>
看这里
免责声明:我没有清理它。
你是对的,你不能使用正则表达式来解析HTML,因为它们不能这样做。
是的,你有其他选择。有几个宽容的HTML解析JS库最初是针对Node的,但应该在浏览器中工作。
- htmlparser
- htmlparser2 HTML5解析器
你也可以利用浏览器内置的HTML解析器,用它来解析你的HTML。在这种情况下,DocumentFragment
可能是有用的。或者,您可以简单地修改contenteditable
元素中的DOM。
这看起来太复杂了。你有没有试过一些更简单的东西,比如:
<p>.+(<br>)+<'/p>
这应该匹配任何包含在段落中的<br>
,在它的最后(在结束标记之前),并且在它自己和开始标记之间有一些东西。你可能应该改变它,使它不接受空格作为有效的东西,但你知道的。
下面是几行jQuery:
// Note: in order to load the html into the dom it needs a root. I'm using `div`:
var input = '<div>' +
'<p>Blah<br><br><br></p> becomes <p>Blah</p>' +
'<p><br></p> stays the same.' +
'</div>';
// Load the html into a jQuery object:
var $html = $(input);
// Get all the `<br>`s at the end of `p`s that are not the only-child:
var $lastBreaks = $html.find('p>:last-child:not(:only-child)').filter('br');
// Remove any immediately preceding `br`s:
$lastBreaks.prevUntil(':not(br)').remove();
// Remove the last `br`s themselves
$lastBreaks.remove();
// Output:
console.log($html.html());
输出:
<p>Blah</p> becomes <p>Blah</p><p><br></p> stays the same.
http://jsfiddle.net/nnH4G/此方法优于使用正则表达式的原因:
你在做什么更明显。当您或其他开发人员稍后回到这个问题时,您不必考虑"regex
%&^@!£%*cthulu&GJHS^&@
到底是做什么的?"更容易扩展/修改。如果你的需求稍微复杂一点,用(JavaScript的)正则表达式是不可能实现的,因为正则表达式和html在Chomsky层次结构中的相对位置。
看到你的代码的人会觉得你是个很酷的人。
正则表达式解决方案(不是说我建议您应该在DOM解析中使用它):
从你的问题中我不清楚你想要发生什么,例如,'<p><br><br></p>'
,所以下面有两个解决方案。
如果你想让它保持原样,你可以使用1);如果你想让它变成'<p></p>'
,你可以使用2):
1)
html = html.replace(
/<p>(['s'S]+?)(?:<br>)+<'/p>/g,
function ( $0, $1 ) { return $1 == '<br>' ? $0 : '<p>' + $1 + '</p>' }
)
测试function test(html) {
return html.replace(
/<p>(['s'S]+?)(?:<br>)+<'/p>/g,
function ( $0, $1 ) { return $1 == '<br>' ? $0 : '<p>' + $1 + '</p>' }
)
}
test( '<p>Blah</p>' ); // <p>Blah</p>
test( '<p>Blah<br><br><br></p>' ); // <p>Blah</p>
test( '<p><br>Blah<br></p>' ); // <p><br>Blah</p>
test( '<p><br></p>' ); // <p><br></p>
test( '<p><br><br></p>' ); // <p><br><br></p>
2)
html = html.replace( /(?:([^>]|[^pb]>)(?:<br>)+|(?:<br>){2,})<'/p>/g, '$1</p>' );
测试function test(html) {
return html.replace( /(?:([^>]|[^pb]>)(?:<br>)+|(?:<br>){2,})<'/p>/g, '$1</p>' );
}
test( '<p>Blah</p>' ); // <p>Blah</p>
test( '<p>Blah<br><br><br></p>' ); // <p>Blah</p>
test( '<p><br>Blah<br></p>' ); // <p><br>Blah</p>
test( '<p><br></p>' ); // <p><br></p>
test( '<p><br><br></p>' ); // <p></p>
- JS可以在Chrome中工作,但不能在Firefox中工作
- WebRTC视频聊天可以在FF中使用,但不能在Chrome中使用
- jQuery Datepicker可以在Safari中工作,但不能在FF或Chrome中工作
- 三角库可以与firefox一起使用,但不能在Chrome中使用
- Highcharts可以从服务器加载数据,但不能更新
- 刷新GoogleMaps tile服务器可以使用JavaScript,但不能使用GWT
- node.js可以识别字符模式,但不能识别数字模式
- 如何在元素中处理鼠标事件,但不能在其子元素上处理
- Json到CSV下载,可以在chrome中工作,但不能在IE浏览器中工作
- jQuery$.post可以在chrome、safari中工作,但不能在FF中工作(声明成功回调函数未定义)
- Javascript可以在chrome中使用,但不能在其他浏览器中使用
- Iframe加载调整大小在Chrome中工作,但不能在IE或Firefox中工作
- Rails Production-可以工作,但不能编辑/删除/创建记录
- 能够在Highcharts中看到值,但不能看到图形
- Django,HTML,JS:<img src=“#">可以在HTML中工作,但不能在JS文件中工作
- 通过Javascript SDK登录Facebook可以在移动设备和本地主机上使用,但不能在台式机上使用
- jQuery/Javascript函数可以在Chrome中使用,但不能在IE11中使用
- 可以将模型传播到组件,但不能传播到sap.ui.jsfragment
- 能够获取元素长度,但不能获取内部 HTML
- 只匹配
如果在但不能直接跟在后面