6

I have searched too much on same topic but not is perfect for what I am looking for.

I have a string like :

var string ='<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>'

Now what I want is to substring it with limit with javascript substring function but don't want tags to be cut in middle like for example

<strong><span>Hii </span> <p

It should be like

<strong><span>Hii </span> <p>

I am using

string.substr(0,200)

string is dynamic variable with html tags

6
  • 1
    i don't know exactly about your meaning...you did't want to break the couple symbol,right? Commented Apr 17, 2015 at 12:26
  • Either look into regex matching, or (hax) make a new element with the HTML code you've got and get its contents. Commented Apr 17, 2015 at 12:28
  • no I don't want to break html tags lets say I have limit my text to 28 characters so it will cut <p> tag but it should check that if tag is not finished then increase limit accordingly or reduce limit accordingly Commented Apr 17, 2015 at 12:28
  • What do you mean? What exactly do you want to cut out? Only the given example? Please post your code with the substring. Commented Apr 17, 2015 at 12:28
  • Is it the text inside the tags you want limited, or the html in whole? Commented Apr 17, 2015 at 12:31

6 Answers 6

5

My solution:

function smart_substr(str, len) {
    var temp = str.substr(0, len);
    if(temp.lastIndexOf('<') > temp.lastIndexOf('>')) {
        temp = str.substr(0, 1 + str.indexOf('>', temp.lastIndexOf('<')));
    }
    return temp;
}

http://jsfiddle.net/8t6fs67n/

Sign up to request clarification or add additional context in comments.

1 Comment

Nice and smart one!
1

Its not elegant but it works, will increase the characters to include the next closing tag https://jsfiddle.net/q680vors/

Just change length to the required number of characters.

var string ='<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>';

var length = 2;
var openTag = 0, closeTag = 0,i=0;
for(i; i<length; i++)
{
    if(string[i] == "<")
        openTag++;
    if(string[i] == ">")
        closeTag++;
}
if(openTag > closeTag)
{
    while(string[i] != ">")
        i++;
}

var newString = string.substring(0,(i+1));

alert(newString);

1 Comment

Just seen this answer stackoverflow.com/a/29699608/1286358, its far more elegant.
1

I don't see reason to do so, but theoretically something like this:

function substrWithTags(str, len) {
    var result = str.substr(0, len),
        lastOpening = result.lastIndexOf('<'),
        lastClosing = result.lastIndexOf('>');

    if (lastOpening !== -1 && (lastClosing === -1 || lastClosing < lastOpening)) {
        result += str.substring(len, str.indexOf('>', len) + 1);
    }

    return result;
}

var s = '<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>'

// <strong><span>Hii </span> <p>this is just a demo <spa
s.substr(0, 53);

// <strong><span>Hii </span> <p>this is just a demo <span>
substrWithTags(s, 53);

Comments

1

I think my function is more accurate when it comes to being more sensitive on the content syntax. If your substring length cuts a word in half for example, the word will be included fully.

function HTML_substring(string, length) {

    var noHTML = string.replace(/<[^>]*>?/gm, ' ').replace(/\s+/g, ' ');
    var subStringNoHTML = noHTML.substr(0, noHTML.indexOf(" ", length));
    var words = subStringNoHTML.split(" ");

    var outPutString = "";
    var wordIndexes = [];

    words.forEach((word, key) => {

        if (key == 0) {

            outPutString += string.substr(0, string.indexOf(word) + word.length);
            wordIndexes[key] = string.indexOf(word) + word.length;

        } else {

            let i = wordIndexes[key - 1];

            outPutString += string.substring(i, string.indexOf(word, i) + word.length);
            wordIndexes[key] = string.indexOf(word, i) + word.length;

        }
    });

    return outPutString;

}

Comments

0

If I understood you correctly, you want to to do something like this?

var limit = 28;
var test = '';
var string = '<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>';

    do {
          test = string.substring(0,limit); 
          limit++;
    } while(test.charAt(test.length-1) !== '>');


test will be equal to '<strong><span>Hii </span> <p>'

or will ends with any another closing tag which is above your limit

1 Comment

my solution is not the best one, look at responce of @SimonPlus
0

Well, I did a function:

function my_substring (str) {
    var answer = [], x;
    for (var i=0, l=str.length; i<l; i++) {
        x = i;
        if (str[i] == '<') {
            while (str[++i] != '>');
            answer.push( str.substring(x, i+1) );
        }
        else {
            while (++i < l && str[i] != '<');
            answer.push( str.substring(x, i) );
            i--;
        }
    }
    return answer;
}

var string = 
"<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>"

console.log ( my_substring(string) );

This code will output:

["<strong>", 
 "<span>", 
 "Hii ", 
 "</span>", 
 " ", 
 "<p>", 
 "this is just a demo ", 
 "<span>", 
 "string", 
 "<span>", 
 "</p>", 
 "</strong>"
]

Then you can select what you want in the array. Hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.