24

I'm working on a project where I need to replace all occurrences of a string with another string. However, I only want to replace the string if it is text. For example, I want to turn this...

<div id="container">
  <h1>Hi</h1>
  <h2 class="Hi">Test</h2>
  Hi
</div>

into...

<div id="container">
  <h1>Hello</h1>
  <h2 class="Hi">Test</h2>
  Hello
</div>

In that example all of the "Hi"s were turned into "Hello"s except for the "Hi" as the h2 class. I have tried...

$("#container").html( $("#container").html().replace( /Hi/g, "Hello" ) )

... but that replaces all occurrences of "Hi" in the html as well

1

5 Answers 5

19

This:

$("#container").contents().each(function () {
    if (this.nodeType === 3) this.nodeValue = $.trim($(this).text()).replace(/Hi/g, "Hello")
    if (this.nodeType === 1) $(this).html( $(this).html().replace(/Hi/g, "Hello") )
})

Produces this:

<div id="container">
    <h1>Hello</h1>
    <h2 class="Hi">Test</h2>
    Hello
</div>

jsFiddle example

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

1 Comment

This doesn't work if there are nested HTML tags, e.g. <h2 class="Hi">Test <span class="Hi"></span></h2>
9

Nice results with:

function str_replace_all(string, str_find, str_replace){
try{
    return string.replace( new RegExp(str_find, "gi"), str_replace ) ;      
} catch(ex){return string;}}

and easier to remember...

Comments

8
 replacedstr = str.replace(/needtoreplace/gi, 'replacewith');

needtoreplace should not rounded by '

Comments

4
//Get all text nodes in a given container
//Source: http://stackoverflow.com/a/4399718/560114
function getTextNodesIn(node, includeWhitespaceNodes) {
    var textNodes = [], nonWhitespaceMatcher = /\S/;

    function getTextNodes(node) {
        if (node.nodeType == 3) {
            if (includeWhitespaceNodes || nonWhitespaceMatcher.test(node.nodeValue)) {
                textNodes.push(node);
            }
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                getTextNodes(node.childNodes[i]);
            }
        }
    }

    getTextNodes(node);
    return textNodes;
}

var textNodes = getTextNodesIn( $("#container")[0], false );
var i = textNodes.length;
var node;
while (i--) {
    node = textNodes[i];
    node.textContent = node.textContent.replace(/Hi/g, "Hello");
}

Note that this will also match words where "Hi" is only part of the word, e.g. "Hill". To match the whole word only, use /\bHi\b/g

1 Comment

This is by far one of the most under rated answers I have seen in a long time. It works extremely well even for running over the entire <body>
0

here you go => http://jsfiddle.net/c3w6X/1/

var children='';

$('#container').children().each(function(){
    $(this).html($(this).html().replace(/Hi/g,"Hello")); //change the text of the children

    children=children+$(this)[0].outerHTML; //copy the changed child
});
var theText=$('#container').clone().children().remove().end().text(); //get the text outside of the child in the root of the element

$('#container').html(''); //empty the container

$('#container').append(children+theText.replace(/Hi/g,"Hello")); //add the changed text of the root and the changed children to the already emptied element 

4 Comments

This doesn't work if there are nested HTML tags, e.g. <h2 class="Hi">Test <span class="Hi"></span></h2>
In this particular example, but I think the OP was asking for a general solution. The example is probably a stripped-down version of his real HTML.
@MattBrowne you're right, j08691 's answer does it though
No it doesn't actually...I'll make the same comment there.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.