2

Input:

<div>Many</div><div>Lines</div><div>Goes</div><div>Here</div>

Expected output:

Many<br>Lines<br>Goes<br>Here

I tried an approach like this:

input = input.replace("<div>", ""),
input = input.replace("</div>", "<br>")

And while that works the solution is not optimal.

Cheers

Roney Michael
  • 3,964
  • 5
  • 30
  • 45
subZero
  • 5,056
  • 6
  • 31
  • 51

4 Answers4

5

Use global regex, instead of strings :

input = input.replace(/<div>/g, '');
input = input.replace(/<\/div>/g, '<br>');

console.log(input); // Many<br>Lines<br>Goes<br>Here<br> 

More details :

replace() function can take, as first parameter :

  • a String, like '</div>'
  • a RegExp, like /<\/div>/

Whatever you're using a String or a RegExp, replace() will find the first match, and replace it. The first match only.
You need to specify that the replace is global (ie. every match should be replaced).

You've got two options to make a global replace :

  • Use regex flags :
    input.replace(/<\/div>/g, '<br>');
  • Use the third parameter, which is a comination of flags :
    input.replace('</div>', '<br>', 'g');

Warning :

The use of the flags parameter in the String.replace method is non-standard. Instead of using this parameter, use a RegExp object with the corresponding flags.

As the third parameter way is not a standart, you're encouraged to use RegExp way.

Just for fun :

You also can do it in a single line :

input = input.replace(/<(\/)?div>/g, function(m, p) { return p ? '<br>' : ''; });
/*
input.replace(
    /<(\/)?div>/g,       -> regex to match '<div>' and '</div>'
    function(m, p) {     -> m = whole match, p = first capturing group
        return p         -> if p is defined, ie. if we've got a slash
            ? '<br>'     -> we matched '</div>', return '<br>'
            : '';        -> we matched '<div>', return ''
    }
);
*/
zessx
  • 68,042
  • 28
  • 135
  • 158
2

You could do:

input = replace(/<div>(.*?)<\/div>/, "$1<br>")

Several other options to perform replace using matched groups can be found in this question's answers.

Community
  • 1
  • 1
Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • 1
    In case you have nested `div` elements, this code will destroy the structure and create semantically invalid HTML code like this: `
    Hello
    ` results in `Hello
    `
    – fero Dec 10 '13 at 11:07
  • 1
    @fero Looking at OP's question it seemed to me that it is not possible to have nested `
    `-s. If that is possible however I can not think of a better option then to use the default(greedy) version of `*` multiple times which will generally perform worse than the solution proposed by zessx.
    – Ivaylo Strandjev Dec 10 '13 at 11:12
  • Yes, you're absolutely right, in both cases. I just wanted to mention that your code won't work with nested `div`s. :-) – fero Dec 10 '13 at 12:22
2

Try to manipulate the DOM. The script below will produce what you need:

DEMO

function insertAfter(referenceNode, newNode) {
    referenceNode.parentNode.insertBefore(
        newNode,
        referenceNode.nextSibling);
}

var divTags = document.getElementsByTagName('div');

for (var i = 0; i < divTags.length;) {
    var div = divTags[i];
    var text = document.createTextNode(div.innerHTML);

    div.parentNode.replaceChild(text, div);
    insertAfter(text, document.createElement('br'));
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
1

It would help if you gave us a better indication of what kind of strings can fall between the <div> and </div>.

http://regexr.com?37j2q

input = input.replace(new RegExp("<div>([a-zA-Z0-9]+)</div>", "mg"), "\$1<br>");

http://jsfiddle.net/2GwQv/2/

rdrkt
  • 138
  • 6