Replace string everywhere except if its within quotes - javascript

I would like to replace all :) by :D, except if they are within quotes "
Example 1:
Hey man :D, how're you? :) My friend told me "this can't be true :)"
becomes
Hey man :D, how're you? :D My friend told me "this can't be true :)"
As you see, :) is not replaced if it's enclosed by ". If this condition wouldn't be there, it would be quite simple, right? I am using Javascript (jQuery) for all this.
If this is not plainly possible with a regex, what would be an alternate suggestion?

Assuming no double quote is unbalanced, this is the regex that should work for you:
:\)(?=(?:(?:[^"]*"){2})*[^"]*$)
Explanation: This regex is using a positive lookahead that basically is matching 0 or more occurrences of a pair of some text until a double quote is found i.e. ([^"]*"){2} on the right hand side (RHS) of every match of :).
Which in simple term means replace a :) only if it is outside double quotes since all the matches inside double quotes will have odd number of [^"]*" matches on RHS.
Live Demo: 1. http://www.rubular.com/r/3aixZy5bYR
Live Demo: 2. http://ideone.com/C679NW

function parseSmiley(str){
return str.replace(/(?!"):\)(?!")/g, ":D");
}
console.log(parseSmiley('Hey man :D, how\'re you? :) My friend told me "this can\'t be true :)"');
And the fiddle with an input so you can test.
Basically, we just replace all instances of :) not encased in " " with :D

If you need variables to control of this - then you could try
function doReplace(find, repl, str, fullWordsOnly, ignoreSQuotes, ignoreDQuotes, caseSensitive) {
if (caseSensitive == undefined) caseSensitive = false;
var flags = 'gm';
if (!caseSensitive) flags += 'i';
var control = escapeRegExp(find);
if (ignoreDQuotes) control = '(?!\\B"[^"]*)' + control + '(?![^"]*"\\B)';
if (ignoreSQuotes) control = '(?!\\B\'[^\']*)' + control + '(?![^\']*\'\\B)';
if (fullWordsOnly) control = '\\b' + control + '\\b';
return str.replace(new RegExp(control, flags), repl);
}
Note, this will probably have problems with single quotes when using abbreviated words such as how're and can't, so I've also included a hack to fix against that:
// Fix any abbreviated words ('re or 't)
str=str.replace(/'re\/b/gi, ''re');
str=str.replace(/'t\b/gi, ''t');
See http://jsfiddle.net/Abeeee/ct7vayz5/4/ for a working demo

Related

javascript regexp "subword" replace

I have a phrase like
"everything is changing around me, wonderfull thing+, tthingxx"
and I want to modify every word that contains ***thing at the end of that word, or at most another character after "thing", like "+" or "h" or "x"...
something like
string = 'everything is changing around me, wonderful thing+, tthingxx'
regex = new RegExp('thing(\\+|[g-z])$','g');
string = string.replace(regex, '<b>thing$1</b>');
what I want? everything is changing around me, wonderful thing+, tthingxx
The result of my regexp? anything working... if I remove the $ all the words containing "thing" and at least another character after it are matched:
everything is changing around me, wonderful thing+, tthingxx
I tryed everything but - in first place I can't understand very well technical english - and second I did't find the answer around.
what I have to do??? thanks in advance
the solution I found was using this regular expression
/thing([+g-z]){0,1}\b/g
or with the RegExp (I need it because I have to pass a variable):
myvar = 'thing';
regex = new RegExp(myvar + "([+g-z]){0,1}\\b" , "g");
I was missing the escape \ when doing the regular expression in the second mode. But this isn't enough: the + goes out of the < b > and I don't really know why!!!
the solution that works as I want is the one by #Qtax:
/thing([+g-z])?(?!\w)/g
thank to the community!
To solve the issue with + not matching when using \b you could use (?!\w) instead of \b there, like:
thing[+g-z]?(?!\w)
Use boundary in your regex
\b\w+thing(\+|[g-z])?\b
If I understand what you want, then:
string = 'everything is changing around me, wonderful thing+, tthingxx';
string = string.replace(/thing(\b|[+g-z]$)/g, '<b>thing$1</b>');
...which results in:
every<b>thing</b> is changing around me, wonderful <b>thing</b>+, tthingxx
\b is a word boundary, so what the regular expression says is anywhere it finds "thing" followed by a word boundary or + or g-z at the end of the string, do the replacement.

Javascript regex expression to replace multiple strings?

I've a string done like this: "http://something.org/dom/My_happy_dog_%28is%29cool!"
How can I remove all the initial domain, the multiple underscore and the percentage stuff?
For now I'm just doing some multiple replace, like
str = str.replace("http://something.org/dom/","");
str = str.replace("_%28"," ");
and go on, but it's really ugly.. any help?
Thanks!
EDIT:
the exact input would be "My happy dog is cool!" so I would like to get rid of the initial address and remove the underscores and percentage and put the spaces in the right place!
The problem is that trying to put a regex on Chrome "something goes wrong". Is it a problem of Chrome or my regex?
I'd suggest:
var str = "http://something.org/dom/My_happy_dog_%28is%29cool!";
str.substring(str.lastIndexOf('/')+1).replace(/(_)|(%\d{2,})/g,' ');
JS Fiddle demo.
The reason I took this approach is that RegEx is fairly expensive, and is often tricky to fine tune to the point where edge-cases become less troublesome; so I opted to use simple string manipulation to reduce the RegEx work.
Effectively the above creates a substring of the given str variable, from the index point of the lastIndexOf('/') (which does exactly what you'd expect) and adding 1 to that so the substring is from the point after the / not before it.
The regex: (_) matches the underscores, the | just serves as an or operator and the (%\d{2,}) serves to match digit characters that occur twice in succession and follow a % sign.
The parentheses surrounding each part of the regex around the |, serve to identify matching groups, which are used to identify what parts should be replaced by the ' ' (single-space) string in the second of the arguments passed to replace().
References:
lastIndexOf().
replace().
substring().
You can use unescape to decode the percentages:
str = unescape("http://something.org/dom/My_happy_dog_%28is%29cool!")
str = str.replace("http://something.org/dom/","");
Maybe you could use a regular expression to pull out what you need, rather than getting rid of what you don't want. What is it you are trying to keep?
You can also chain them together as in:
str.replace("http://something.org/dom/", "").replace("something else", "");
You haven't defined the problem very exactly. To get rid of all stretches of characters ending in %<digit><digit> you'd say
var re = /.*%\d\d/g;
var str = str.replace(re, "");
ok, if you want to replace all that stuff I think that you would need something like this:
/(http:\/\/.*\.[a-z]{3}\/.*\/)|(\%[a-z0-9][a-z0-9])|_/g
test
var string = "http://something.org/dom/My_happy_dog_%28is%29cool!";
string = string.replace(/(http:\/\/.*\.[a-z]{3}\/.*\/)|(\%[a-z0-9][a-z0-9])|_/g,"");

Delete a string in javascript, without leaving an empty space?

I've seen multiple instance of that kind of question, but not the one I'm looking for specifically... (I just hope I'm not hopelessly blind ! :P)
Let's consider this code:
var oneString = "This is a string";
document.write(oneString.replace("is", ""));
I would have assumed that the output would have been:
This a string.
But this is the output I'm getting:
This a string
It's like replace() think that the second argument sent is " " and not ""... What would be the proper manner then to strip the string of a given string, without having extra spaces floating in my output ?
You are actually getting "is" replaced with an empty string, it's the space before and after the "is" you replace that stay around as the two spaces you see. Try;
oneString.replace("is ", "")
Are you sure you're not getting "This a string"?
I think you should replace "is " with "" to get your desired output. There is a space before as well as after the word.
Look at the original string - "This_is_a_string" (I replaced spaces with underscores). When you remove "is", you don't touch either of the surrounding spaces, so both end up in the output. What you need to do is oneString.replace("is","").replace(/ +/," ") -- get rid of "is" and then eliminate any double spaces. If you want to keep some double spaces, try oneString.replace(" is","") instead, though you will run into issues if the string starts with is (eg "is it safe?").
The best answer might be something like oneString.replace(/is ?/,"") to match is possibly followed by a space oroneString.replace(/ ?is ?/," ") to match is possibly surrounded by spaces, and replace all of them with one space.
You didn't include any spaces in your pattern. When I try your code in Chrome I get:
> "This is a string".replace("is","")
"Th is a string"
One way to accomplish what you're trying would be to use a regexp instead:
> "This is a string".replace(/is\s/,"")
"This a string"
var aString = "This is a string";
var find = "is"; // or 'This' or 'string'
aString = aString.replace(new RegExp("(^|\\s+)" + find + "(\\s+|$)", "g"), "$1");
console.log(oneString);
The only case where this isn't perfect is when you replace the last word in the sentence. It will leave one space at the end, but I suppose you could check for that.
The g modifier is to make the replace replace all instances, and not just the first one.
Add the i modifier to make it case insensitive.
If you also want this to work on strings like:
"This has a comma, in it"
Change the regexp to:
var find = "comma";
new RegExp("(^|\\s+)" + find + "(\\s+|$|,)", "g")

Javascript regex with deep objects replacement issue

Hey all, having an issue doing string replacement for template engine code I am writing. If my tokens are 1 level deep everything works fine. Example {someProperty}. But if I try searching for a nested object it never does the replace. Example {myobj.deep.test}. I've attached the code I am playing around with. Thanks for the help!
function replaceStuff(content, fieldName, fieldValue) {
var regexstr = "{" + fieldName + "}";
console.log("regexstr: ", regexstr);
//var regex = new RegExp("{myobj\.deep\.test}", "g"); //this works as expected
var regex = new RegExp(regexstr, "g"); //this doesn't
return content.replace(regex, fieldValue);
}
replaceStuff("test: {myobj.deep.test}", "myobj.deep.test", "my value");
See this SO question about curly braces. Perhaps your browser of choice isn't as understanding as chrome is?
You need to escape the '.' characters in the string you're passing in as the fieldName parameter. Ditto for any other special regex characters that you want to be interpreted literally. Basically, fieldName is being treated as part of a regex pattern.
If you don't want fieldName to be evaluated as regex code, you might want to consider using string manipulation for this instead.
Edit: I just ran your code in FireFox and it worked perfectly. You may have something else going on here.

JavaScript - Regular Expressions

I have an HTML page with a text box. This text box has an id of "myTextBox". I am trying to use a regular expression in JavaScript to replace certain values in the text box with another value. Currently, I am trying the following
function replaceContent()
{
var tb = document.getElementById("myTextBox");
if (tb != null)
{
var current = new String(tb.value);
var pattern = new RegExp("(ft.)|(ft)|(foot)", "ig");
current = current.replace(pattern, "'");
alert(current);
}
}
Based on this code, if I had the value "2ft" in the myTextBox, I would expect the current variable to be "2'". However, it always shows an empty string. I fear there is something that I am misunderstanding in relation to regular expressions in JavaScript. What am I doing wrong?
Thank you!
Rewrite your pattern to:
(ft\.?|foot|feet)
This will match "ft" or "ft." and "foot" or "feet".
When writing code that uses regular expressions that won't behave, assume (first) that it is your regex that is the problem. Thanks to the compact and esoteric "programming" of regular expressions, it's quite easy to make a mistake you don't see.
If you test the following in Firebug to yield a correct result:
"2ft".replace(/(ft\.?|foot|feet)/ig, "'")
You will get "2'" in your console.
So this answer ought to solve your problem, if the regex is your problem in the first place. Like Rubens said, please check the ID of your textbox and ensure that the item is correctly retrieved.
As The Wicked Flea says, the literal '.' in your regex needs to be escaped. If it's in a character class it can be written un-escaped, but outside of one it must be escaped.
The following works for me:
<script>
var current = "2ft";
var pattern = new RegExp("(ft.)|(ft)|(foot)", "ig");
current = current.replace(pattern, "'");
alert(current);
</script>
Are you sure that tb.value is evaluating properly?
I ran your code using IE8,Chrome and FF3 with no problems.
Please check if your textbox id is correct.
The problem is that you're alternating explicit groupings. Instead you can just do something like the following:
function replaceContent()
{
var tb = document.getElementById("myTextBox");
if (tb != null) {
current = tb.value.replace(/\s*(ft\.|ft|foot|feet)\b/ig, "'");
alert(current);
}
}
Also, note the \s* which will strip leading spaces and the \b which marks the beginning/end of a word. I also added feet.

Categories