0

I'd like to select all occurances of <br /> that are within a paragraph <p></p> with a regular expression in JS. Currently I just select all <br /> like this:

var regex = /<br\s*[\/]?>/gi;

But doing this gives me trouble at some point because of what I'm trying to do with the selection. I need a more precise regex since breaks in headlines etc. are irrelevant to me.

If you are wondering about the context of this, I want to replace the <br />'s with two paragraphs with suitable classes to act like a <br /> but to indent the text after the break like this:

function removeEmptyNodes(selector)
{
    $(selector).each(function() {
        if  ($(this).html().replace(/\s|&nbsp;/g, '').length == 0)
            $(this).remove();
    });
};
function assignIndents()
{
    var str = $("#content").html();
    var regex = /<br\s*[\/]?>/gi;
    $("#content").html(str.replace(regex, "</p><br /><p>"));
    $('br').prev('p').addClass('br');
    $('br').next('p').addClass('indent');
    removeEmptyNodes('#content p');
    $('br').next('.scroller').children('p').first().addClass('indent');
    $('br').replaceWith('');
    removeEmptyNodes('#content p');
};

Edit:

My goal is that I have a paragraph with one or several line breaks. Like this simple case: <p>with some text <br />and another line<p>. I want the text after the line breaks to be indented and to be in a p of their own. So I need to split my original p. I don't want to add in divs or anything else nested in the original paragraphs. I need a bunch of sibling p tags at the end like this: <p class="br">with some text</p><p class="indent">and another line<p> By which way I replace the <br />'s to split the p's does not matter to me...

C.O.
  • 2,281
  • 6
  • 28
  • 51
  • 4
    Don't parse HTML with regex: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – George Cummins Jun 17 '11 at 17:08
  • This is probably better handled by finding the `
    ` with jQuery and appending the appropriate `

    ` nodes where you want them.

    – Michael Berkowski Jun 17 '11 at 17:09
  • @micheal I want to split an existing p, adding p's in the manner you describe would create nested p's in my original p I think – C.O. Jun 17 '11 at 17:27

2 Answers2

5

Why don't you just find all without a regex?

$('p').each(function(){
    var brs = $('br', this); //all <br>s withing this <p>
    //do something with brs
});

Fiddle: http://jsfiddle.net/maniator/Ra8ax/


UPDATE:

Here is what you want with your new spec:

$('p').each(function(){

    var html = this.innerHTML;
    var htmlArray = html.split('<br>');
    var new_html = htmlArray[0];

    for(var i = 1; i < htmlArray.length; i++){
        new_html += "<div class='break'>"+htmlArray[i]+"</div>";
    }

    this.innerHTML = new_html;

});

Fiddle: http://jsfiddle.net/maniator/Ra8ax/8/


UPDATE with no nesting:

JS:

$('p').each(function(){

    var html = this.innerHTML;
    var htmlArray = html.split('<br>');
    var new_html = "<p>"+htmlArray[0]+"</p>";

    for(var i = 1; i < htmlArray.length; i++){
        new_html += "<p class='break'>"+htmlArray[i]+"</p>";
    }

    $(this).replaceWith(new_html);

});

Fiddle: http://jsfiddle.net/maniator/Ra8ax/11/

Naftali
  • 144,921
  • 39
  • 244
  • 303
  • because in order to add the "

    " which splits the original `

    ` in two at the position where the `
    ` was I need to get at the surrounding html not at the contents of the `

    `

    – C.O. Jun 17 '11 at 17:11
  • @C.O. -- what do you mean? did you view my fiddle example? – Naftali Jun 17 '11 at 17:13
  • @Neal Thank you for the update but it's still the one p with nested divs inside that have some format. Splitting into several p's is important to my objective. – C.O. Jun 17 '11 at 17:43
  • @Neal That would make nested paragraphs. I wanted all of them to be siblings. I tried to point that out but apparenty it was not clear enough... – C.O. Jun 17 '11 at 17:49
  • @C.O. -- here it is without nested `

    ` -- http://jsfiddle.net/maniator/Ra8ax/11/

    – Naftali Jun 17 '11 at 17:50
  • @Neal Perfect. Thank you so much. You might want to edit you update of the answer above to show the final version. – C.O. Jun 17 '11 at 17:52
  • @Neal Turns out to be a royal mess... **Original XHTML:**
    **InnerHTML in FF 4, IE9, Safari, Chrome:**
    **In IE8 :**
    **In Opera:**
    – C.O. Jun 17 '11 at 18:12
  • hmmmm use `$(this).html()` it should return the same for all – Naftali Jun 17 '11 at 18:28
  • Nope it doesn't.. but I used this: var brLooksLike=$('


    ').first().html(); That gets each browser's flavor of a br...
    – C.O. Jun 17 '11 at 18:31
  • Sounds like you found a solution ^_^ – Naftali Jun 17 '11 at 18:33
3

Use a Jquery selector instead of regex: $('p br')


Update 2:
$('#content')
  .contents()
  .filter(function() {
    return this.nodeType == Node.TEXT_NODE;
  })
  .wrap("<p>");

var br = $('#content br');
br.prev('p').addClass('br');
br.next('p').addClass('indent');
br.remove();

http://jsfiddle.net/wWsht/

js1568
  • 7,012
  • 2
  • 27
  • 47
  • Next p doesn't yet exist. That is what the original regex replace creates. Is there a better way to do that? – C.O. Jun 17 '11 at 17:30