Javascript中带有HTML标记的子字符串文本

Javascript中带有HTML标记的子字符串文本,javascript,html,tags,substring,Javascript,Html,Tags,Substring,您有在Javascript中使用HTML标记对文本进行子串的解决方案吗 例如: var str = 'Lorem ipsum <a href="#">dolor <strong>sit</strong> amet</a>, consectetur adipiscing elit.' html_substr(str, 20) // return Lorem ipsum <a href="#">dolor <strong>si

您有在Javascript中使用HTML标记对文本进行子串的解决方案吗

例如:

var str = 'Lorem ipsum <a href="#">dolor <strong>sit</strong> amet</a>, consectetur adipiscing elit.'

html_substr(str, 20)
// return Lorem ipsum <a href="#">dolor <strong>si</strong></a>

html_substr(str, 30)
// return Lorem ipsum <a href="#">dolor <strong>sit</strong> amet</a>, co
var str='Lorem ipsum,concetetur adipsicing elit'
html_substr(str,20)
//回盲
html_substr(str,30)
//返回Lorem ipsum公司

Javascript有一个子字符串方法。如果字符串包含html,则没有区别


参见使用类似于
=str.replace(/]*>?/gi,”)的东西。substr(0,20)
我在以下位置创建了一个示例:

用法:

var str = 'Lorem ipsum <a href="#">dolor <strong>sit</strong> amet</a>, consectetur adipiscing elit.';

var res1 = html_substr( str, 20 );
var res2 = html_substr( str, 30 );

alert( res1 ); // Lorem ipsum <a href="#">dolor <strong>si</strong></a>
alert( res2 ); // Lorem ipsum <a href="#">dolor <strong>sit</strong> amet</a>, co
var str='Lorem ipsum,concetetur adipsicing elit';
var res1=html_substr(str,20);
var res2=html_substr(str,30);
警报(res1);//乱数假文
警报(res2);//Lorem ipsum公司
示例:


功能:

function html_substr( str, count ) {

    var div = document.createElement('div');
    div.innerHTML = str;

    walk( div, track );

    function track( el ) {
        if( count > 0 ) {
            var len = el.data.length;
            count -= len;
            if( count <= 0 ) {
                el.data = el.substringData( 0, el.data.length + count );
            }
        } else {
            el.data = '';
        }
    }

    function walk( el, fn ) {
        var node = el.firstChild;
        do {
            if( node.nodeType === 3 ) {
                fn(node);
                    //          Added this >>------------------------------------<<
            } else if( node.nodeType === 1 && node.childNodes && node.childNodes[0] ) {
                walk( node, fn );
            }
        } while( node = node.nextSibling );
    }
    return div.innerHTML;
}
函数html\u substr(str,count){ var div=document.createElement('div'); div.innerHTML=str; 步行(分区、跑道); 功能轨道(el){ 如果(计数>0){ var len=el.data.length; 计数-=len;
如果(count>------------------------------------考虑到这一点,这里有一个解决方案可以做到这一点:)

编辑:只是想澄清一下:这不是一个有效的解决方案,这是一个对输入字符串做了非常宽松的假设的练习,因此应该谨慎对待。阅读上面的链接,看看为什么用正则表达式解析html永远无法完成

函数htmlSubstring(s,n){ 变量m,r=/\s]*)[^>]*>/g, 堆栈=[], lasti=0, 结果=''; //对于每个标记,虽然我们没有足够的字符 而((m=r.exec))&&n){ //获取最后一个标记和此标记之间的文本子字符串 var temp=s.substring(lasti,m.index).substr(0,n); //追加到结果并计算添加的字符数 结果+=温度; n-=温度长度; lasti=r.lastIndex; 如果(n){ 结果+=m[0]; if(m[1].indexOf('/')==0){ //如果这是一个结束标记,则弹出堆栈(不考虑坏的html) stack.pop(); }else如果(m[1].lastIndexOf('/')!==m[1].length-1){ //如果这不是一个自动关闭标记,则将其推入堆栈中 stack.push(m[1]); } } } //如果需要,添加字符串的其余部分(此处没有更多标记) 结果+=s.substr(lasti,n); //修复未关闭的标签 while(堆栈长度){ 结果+=''; } 返回结果; }
示例:


注意:对于糟糕的html可能更安全,但我不确定它处理空白的能力。

这是针对单个标记的解决方案

function subStrWithoutBreakingTags(str, start, length) {
    var countTags = 0;
    var returnString = "";
    var writeLetters = 0;
    while (!((writeLetters >= length) && (countTags == 0))) {
        var letter = str.charAt(start + writeLetters);
        if (letter == "<") {
            countTags++;
        }
        if (letter == ">") {
            countTags--;
        }
        returnString += letter;
        writeLetters++;
    }
    return returnString;
}
不带breakingtags(str、start、length)的函数子字符串{
var-countTags=0;
var returnString=“”;
var writeLetters=0;
而(!((writeLetters>=length)和&(countTags==0))){
变量字母=str.charAt(开始+写字母);
如果(字母==“”){
计数标签--;
}
returnString+=字母;
writeLetters++;
}
返回字符串;
}
让str='Lorem ipsum,Concetetur Adipsicing Elite'
让明文=htmlString.replace(/]+>/g',);

使用上述给定的正则表达式提取纯文本,然后使用基于JS字符串的“.substr()”函数以获得所需的结果

是的,我知道。但我的问题是,当我使用substr时,html标记可能会被破坏。在这种情况下,您需要使用递归正则表达式之类的东西来平衡html标记。但这将是一个非常复杂的实现过程。您似乎希望子字符串忽略标记,但在最终结果。我认为您需要将字符串转换为DOM元素,遍历元素,计算文本节点中的字符数,并删除所有字符(或文本节点)这超出了你的计算范围。尽管如此,我还是觉得浏览器之间在空白方面可能存在一些差异。不确定。发布了一个答案。似乎给出了你想要的结果,但浏览器之间在空白方面可能存在一些差异。不确定。在不破坏html的情况下使用子字符串html代码[this][1]. [1]在这个例子中,标签被维护了。我不认为简单的返回<代码> DIV.InEntHeld就足够了。考虑如果在剪切点之后有更多的标签会发生什么。它们会在最后的字符串中结束,但是空的…我想曾经是<代码>。count@Dan:是的,那是真的。我不确定是哪一个需要。可能是潜在的空标记应该作为DOM结构的一部分保留在适当的位置。但是您是对的,如果不是这样,那么您应该执行
el.parentNode.removeChild(el)
相反。EDIT:实际上,这会打乱DOM漫游。@patrick dw:这是一个删除剩余节点的方法。这个解决方案很好。但是非成对标记(img、hr,…)存在一些问题.Works很棒!@honzahommer:你能举一个给你带来麻烦的HTML字符串的例子吗?另外,对于完全清空的标记(其全部内容超过计数的标记),你想做什么?这些标记应该被删除,还是保留为空标记?
'/>
不要用正则表达式解析html-对于你拥有的每个正则表达式,你都可以找到html来打破它。@Zirak:我知道:)你真的读了我发布的第一句话中的第一个链接了吗?:)也读了我的最后一句话:P我知道这不是正确的解决方案,但我没有虽然这对我来说是一个有趣的练习,但如果我真的这么做了,为什么不发布它呢。所以你知道它不好,但你还是建议它?我的例子不是无效的或糟糕的html。它是完全有效的。对验证器运行它,它不会发出噪音。无效的是你的正则表达式,因为它不能匹配所有有效的html。@Zirak:我从来没有说过这是有效的有效解
function subStrWithoutBreakingTags(str, start, length) {
    var countTags = 0;
    var returnString = "";
    var writeLetters = 0;
    while (!((writeLetters >= length) && (countTags == 0))) {
        var letter = str.charAt(start + writeLetters);
        if (letter == "<") {
            countTags++;
        }
        if (letter == ">") {
            countTags--;
        }
        returnString += letter;
        writeLetters++;
    }
    return returnString;
}
let str = 'Lorem ipsum <a href="#">dolor <strong>sit</strong> amet</a>, consectetur adipiscing elit.'
let plainText = htmlString.replace(/<[^>]+>/g, '');