I want to replace "Bob" with "John", but if "Bub" is inside the parentheses, it shouldn't be changed.
Input: Bob comes home today, but he (Bob) will not stay long. I will call Bob and tell him (Bob) to come tomorrow.
Output: John comes home today, but he (Bob) will not stay long. I will call John and tell him (Bob) to come tomorrow.
Could it be done by split() to split out all instances of "(Bob)" and save them in an temporary array, then change all instaces of "Bob" to "John". Now we can put back all unchainged "(Bob)" from the array to the string?
var string = "Bob comes home today, but he (Bob) will not stay long. I will call Bob and tell him (Bob) to come tomorrow.
";
string = string.replace(/([^(]|^)Bob([^)]|$)/ig,"$1John$2");
Or, you can use three regular expressions in a row, but this has the possibility of error and isn't as elegant as the first.
Code:
var string = "Bob comes home today, but he (Bob) will not stay long. I will call Bob and tell him (Bob) to come tomorrow.
";
string = string.replace(/\(Bob\)/ig,"DO!NOT!REPLACE").replace(/Bob/ig,"John").replace(/DO!NOT!REPLACE/ig,"(Bob)");
Great wit and madness are near allied, and fine a line their bounds divide.
W3Schools.
And
/ Starts the RegExp
( something ) is what the $1 refers to
[^(] means not a bracket
| or
^ start of string
Bob pretty obvious
() this time is what $2 refers to
[^)] means the same as before
| or again
$ end of string
/ end of regexp
i means case insensitive
g means global, basically keep going after one match
Great wit and madness are near allied, and fine a line their bounds divide.
Thank u. and good link. i will check that site.
I wonder if it is possible to use RegExp in a loop.
If i have 100 names (Bob, George, ...) that i want to change to (John, Michael, ...). I tested this script with no result. RegExp seems to have problem with for-loop. The script works fine without for-loop. Any ideas?
Working script:
--------------
var inStr ="Bob likes (Bob) but he (Bob) saw Bob today. I will call Bob and tell him (Bob) to come tomorrow.";
var oldWord = "Bob";
var newWord = " John ";
var regExpStr = "([^(]|^)"+oldWord+"([^)]|$)";
var regExpObj = new RegExp(regExpStr, "ig");
document.f1.t1.value = inStr.replace(regExpObj, newWord);
---------------
Not working script:
--------------------
var inStr ="Bob likes (Bob) but he (Bob) saw Bob today. I will call Bob and tell him (Bob) to come tomorrow.";
var oldWordArr = new array(); oldWordArr = ["i","will","call","Bob"];
var newWordArr = new array(); newWordArr = ["you","must","telephone","John"];
for (var i = 0; i < 4; i++){
var regExpStr = "([^(]|^)"+oldWordArr[i]+"([^)]|$)";
var regExpObj = new RegExp(regExpStr, "ig");
document.f1.t1.value = inStr.replace(regExpObj, newWordArr[i]);
}
--------------------
Thx for reply.
I found out that one problem that was syntax error (should be "new Array" not "new array"). Now I can get Bob to John but the others will not change. Do I need to change the RegExp expression?
You're doing every replace, but you're doing them all on the original string. So you replace all the "i"s, and set t1 to that value, then you replace all the "will"s (in the ORIGINAL string, not your updated one) and set t1 to that value, and so on and so forth till you replace all "Bob"s and set t1 to that value, leaving you with only that version.
Also, the replacement string was "$1John$2", "$1" and "$2" are important, your modified code misses them.
Yep, Y_Less is spot on. They are all being replaced, it's just that you're only seeing the last one, and they are not all applied to the same string.
Code:
var inStr ="Bob likes (Bob) but he (Bob) saw Bob today. I will call Bob and tell him (Bob) to come tomorrow.";
var oldWordArr = ["i","will","call","Bob"];
var newWordArr = ["you","must","telephone","John"];
for (var i = 0; i < 4; i++){
var regExpObj = new RegExp("([^(]|^)"+oldWordArr[i]+"([^)]|$)", "ig");
inStr = inStr.replace(regExpObj, "$1"+newWordArr[i]+"$2");
}
document.f1.t1.value = inStr;
You can see the short way of making an array, I removed an unnecessary variable (technically you don't need regExpObj either, but it's clearer with it), and I added back in the $1 and $2. You can also see that I apply all the changes to the same string, what you did, and what Y_Less said, is do them all on the original string, and then overwrite the result.
Great wit and madness are near allied, and fine a line their bounds divide.
well nearly perfectly ;-)
inStr ="I (will) call (Bob).";
Ouput: you (wyoull) telephone (Bob).
How can i define RegExp so no matter which alphabet, it shouldn't change inside brackets. It seems that it has changes "i" in the will to "you". It should just jump över all brackets without checking what is inside.
Actually, you can replace the whole thing with this. It checks that it's not followed an opening bracket.
new RegExp(oldWordArr[i]+"(?![^(]*\))", "ig");
EDIT: The replace string in this case will not include "$1John$2" because look ahead (what that feature is called) is NOT matched. On the other hand, the business with (not a bracket or start of string) was matched, so the match was " Bob " not just "Bob". Here the match will just be what oldWordArr[i], nothing more.
Last edited by Declan1991; 08-13-2009 at 03:12 PM.
Great wit and madness are near allied, and fine a line their bounds divide.
Oh sorry. It needs a double backslash because it is in a string.
new RegExp(oldWordArr[i]+"(?![^(]*\\))", "ig");
If it was /bob(?![^(]*\))/ig there is only one backslash. I tested it as that.
Great wit and madness are near allied, and fine a line their bounds divide.
is it possible to avoid using regExp constructor so we can have a single line like this:
inStr = inStr.replace(oldWordArr[i]+"/(?![^(]*\))/ig", newWordArr[i]);
I am not sure if "ig" is allowed to be placed in there.
Bookmarks