views:

142

answers:

2

I'm trying to replace all periods with the degree symbol. Using the each method only replaces the first period inside the paragraph tag, not all of them. I'm also trying to make the periods inside the anchor tags to be ignored and not replaced, so the links won't be disrupted by my code. Can anyone help?

$('div.post').each(function(){
    var $h = $(this);
    $h.html( $h.html().replace( '.', '<span class="period">&deg;<\/span>' ) );
});

Edit: I should have mentioned, I want to retain the 'period' class which makes it tricky.

A: 

A regex with the g flag (global) should work to replace all of them:

$h.html( $h.html().replace(/\./g, '<span class="period">&deg;<\/span>' ) );

Not matching periods within anchor tags is a significantly harder problem, since regular expressions don't have a sense of hierarchical context within an HTML document. The best approach I could think of would be to recurse through all of the sub-items within the item whose HTML you're targeting and replace within them, skipping them if it's an anchor element.

Amber
-1 This would also replace periods in anchors which the poster specifically said he did not want to target.
Darko Z
Yes, hence my note to the OP. I'm curious, however, why you downvoted this and not the other answer that says exactly the same thing.
Amber
I down voted both :) somebody else upvoted it though.
Darko Z
Anyhow, I would figure that a partial answer (to the first part of the question) would at least be somewhat useful, since the OP didn't appear to know how to do a global replace.
Amber
Seriously. I'll take my answer away before I suffer the wrath of Darko Z. :p You can just edit yours to have the appropriate jquery selections Dav.
zombat
Phear me! In all seriousness though this should be possible with a good regex. Have no time right now to investigate it but maybe later on :)
Darko Z
Hmm it seems a vote gets too old to change after a few minutes so can't undo it sorry ....
Darko Z
It may seem like it can be done with regex, but there are a significant number of hidden gotchas when it comes to dealing with context-awareness if potentially recursive/nested markup.
Amber
+1  A: 
var span = $('<span class="period">°</span>').get(0);

$('p, p *').each(function (index,element) {
    $.each(element.childNodes, function (index,node) {
        if (node.nodeType == 3) {
            $.each(node.nodeValue.split('.'), function (index,fragment) {
                if ( index > 0 ) {
                    element.insertBefore(span.cloneNode(true),node);
                }
                element.insertBefore(document.createTextNode(fragment),node);
            });
            element.removeChild(node);
        }
    });
});

will solve the problem. The key idea is to split the contents of each text node within a paragraph on the "." character, turn each fragment into a new text node, and then assemble the new text nodes with the span elements containing the degree symbols between them.

Rich
Thank you so much! Worked perfectly.
buttonstack
You're welcome. Could you accept the answer?
Rich