Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将HTML字符串中的所有空格与JavaScript匹配_Javascript_Html_Regex_Replace - Fatal编程技术网

将HTML字符串中的所有空格与JavaScript匹配

将HTML字符串中的所有空格与JavaScript匹配,javascript,html,regex,replace,Javascript,Html,Regex,Replace,假设您有如下HTML字符串: <div id="loco" class="hey" >lorem ipsum pendus <em>hey</em>moder <hr /></div> lorem ipsum pendus heymoder 并且需要在每个空格字符后面放置元素。。。。我正在做的是: HTMLtext.replace(/\s{1,}/g, ' <br/>'); 替换(/\s{1,}/g,“”); 然而

假设您有如下HTML字符串:

<div id="loco" class="hey" >lorem ipsum pendus <em>hey</em>moder <hr /></div>
lorem ipsum pendus heymoder
并且需要在每个空格字符后面放置

元素。。。。我正在做的是:

HTMLtext.replace(/\s{1,}/g, ' <br/>');
替换(/\s{1,}/g,“
”);
然而,问题是,这也会在标记之间(标记属性之间)的空格字符后插入分隔符,我当然只想对标记文本内容这样做。不知怎么的,我对正则表达式总是很不熟悉——有人能帮我吗


因此,基本上要进行我最初的空白匹配,但前提是它不在<和>?

正则表达式不是一个很好的工具。您应该使用DOM,而不是原始HTML字符串

对于一个快速而肮脏的解决方案,它假定字符串中除了分隔标记的字符外没有
字符,您可以尝试以下方法:

result = subject.replace(/\s+(?=[^<>]*<)/g, "$&<br/>");
result=subject.replace(/\s+(?=[^]*有关迭代dom和用

元素替换空白的信息,请参阅。修改后的代码为:

(function iterate_node(node) {
    if (node.nodeType === 3) { // Node.TEXT_NODE
        var text = node.data,
            words = text.split(/\s/);
        if (words.length > 1) {
            node.data = words[0];
            var next = node.nextSibling,
                parent = node.parentNode;
            for (var i=1; i<words.length; i++) {
                var tnode = document.createTextNode(words[i]),
                    br = document.createElement("br");
                parent.insertBefore(br, next);
                parent.insertBefore(tnode, next);
            }
        }
    } else if (node.nodeType === 1) { // Node.ELEMENT_NODE
        for (var i=node.childNodes.length-1; i>=0; i--) {
            iterate_node(node.childNodes[i]); // run recursive on DOM
        }
    }
})(content); // any dom node
(函数迭代节点(node){
如果(node.nodeType==3){//node.TEXT\u节点
var text=node.data,
words=text.split(/\s/);
如果(单词长度>1){
node.data=字[0];
var next=node.nextSibling,
parent=node.parentNode;
对于(变量i=1;i=0;i--){
迭代_节点(node.childNodes[i]);//在DOM上运行递归
}
}
})(内容);//任何dom节点

()

好的,所以您不希望匹配HTML标记中的空格。只有正则表达式不足以满足此要求。我将使用a来完成此工作。您可以看到输出

var lexer=新lexer;
var结果=”;
addRule(//,函数(c){//标记的结尾
this.state=0;//返回状态0-初始状态
结果+=c;//复制到输出
},[2]);//仅当处于状态2时应用此规则
lexer.addRule(/。|\n/,函数(c){//匹配任何字符
结果+=c;//复制到输出
},[2]);//仅当处于状态2时应用此规则
lexer.addRule(/\s+/,函数(){//匹配一个或多个空格
结果+=“
”;//替换为“
” }); lexer.addRule(/。|\n/,函数(c){//匹配任何字符 结果+=c;//复制到输出 })其他一切 lexer.input='lorem ipsum pendus heymoder
'; lexer.lex();

当然,lexer是一个非常强大的工具。您也可以跳过标记中属性值内的尖括号。但是我将留给您来实现。祝您好运。

在一般情况下,使用正则表达式解析HTML是不可能的。只有当您知道HTML源以特定方式受到约束时,才能完成此操作。如果它真的可以是任意的HTML片段,那么你就不能用正则表达式来实现。将HTML交给浏览器,让它构建一个DOM片段,然后查找文本节点并修改它们。谢谢,是的,我知道这些问题,但我并不是真的解析HTML。只是尝试获取空白字符。我正在这样做在一个由我控制的HTML的有限环境中,我可以用DOM来实现它(我最初就是这么做的)-但我正试图避免这种情况,因为DOM操作成本很高,我正试图对代码进行一些优化。问题是,为了确定哪些空白字符需要替换,哪些不需要,你必须非常接近解析HTML。只是为了确保它不在<和>-不关心其他任何事情…但不要没有那么复杂的情况,我不认为是的,如果你确定属性值中没有尖括号,没有CDATA节等,那应该没问题。我想前面应该是
[^]*(@Bergi:我想我们不想在最后一个标记后插入

,是吗?我不确定…谢谢@TimPietzcker-这似乎很好!我已经在DOM中使用了它,但这实际上是一种优化我的JS代码的尝试。该函数可以处理大量文本,因此直接修补DOM并不是最好的解决方案t我想。你能帮我解释一下吗?我假设它是匹配的空格,只要它不在<和>之间,对吗?@Tim:也许不在最后一个单词之后(假设有空格),但如果前面没有标记,则仍应替换任何空格。@Michael:我已编辑了我的答案。希望这能让答案更清楚。请务必考虑Bergi的建议-如果要匹配字符串中最后一个标记后的空格,则需要使用
/\s+(?=[^]*(?:谢谢,但正如其他评论中提到的,这是一次优化尝试。我在DOM中已经有过这种尝试,但理论是DOM操作的成本比仅仅玩字符串要高很多。这也是有意义的。我在这里快速检查了一下,看它是否更快,是的-在大多数浏览器上,它的速度是原来的两倍…@Michael:谢谢你的帮助非常有趣的是,Safari操纵DOM的速度与正则表达式一样快(而且总体上是最快的),因此这不是正则表达式的内置优势。是的,我也对此感到惊讶——但我认为这是Safari 6(或支持jsperf的基准JS)中的一个bug.我刚刚用旧版Safari 5.1进行了测试,结果与其他浏览器相同。加上iPhone/iPad/Chrome上类似的WebKit引擎都是一样的…最后,修补DOM的速度与纯数学/字符串操作的速度是一样的,这也是毫无意义的…谢谢Aadit-这是一个非常有趣的库,但我并没有将外部代码放入其中,因为我正在尝试优化我的代码。另外,通过快速查看库源代码,您仍然在使用正则表达式,对吗?是的,我是。为什么要重新发明轮子?=)
(function iterate_node(node) {
    if (node.nodeType === 3) { // Node.TEXT_NODE
        var text = node.data,
            words = text.split(/\s/);
        if (words.length > 1) {
            node.data = words[0];
            var next = node.nextSibling,
                parent = node.parentNode;
            for (var i=1; i<words.length; i++) {
                var tnode = document.createTextNode(words[i]),
                    br = document.createElement("br");
                parent.insertBefore(br, next);
                parent.insertBefore(tnode, next);
            }
        }
    } else if (node.nodeType === 1) { // Node.ELEMENT_NODE
        for (var i=node.childNodes.length-1; i>=0; i--) {
            iterate_node(node.childNodes[i]); // run recursive on DOM
        }
    }
})(content); // any dom node
var lexer = new Lexer;

var result = "";

lexer.addRule(/</, function (c) { // start of a tag
    this.state = 2; // go to state 2 - exclusive tag state
    result += c; // copy to output
});

lexer.addRule(/>/, function (c) { // end of a tag
    this.state = 0; // go back to state 0 - initial state
    result += c; // copy to output
}, [2]); // only apply this rule when in state 2

lexer.addRule(/.|\n/, function (c) { // match any character
    result += c; // copy to output
}, [2]); // only apply this rule when in state 2

lexer.addRule(/\s+/, function () { // match one or more spaces
    result += "<br/>"; // replace with "<br/>"
});

lexer.addRule(/.|\n/, function (c) { // match any character
    result += c; // copy to output
}); // everything else

lexer.input = '<div id="loco" class="hey" >lorem ipsum pendus <em>hey</em>moder <hr /></div>';

lexer.lex();