Javascript RegExp replace. How to carry unknown characters into replacement? - javascript

I'm trying to get a much deeper understanding of JS RegExp for a project I'm working on.
So if I were checking for all strings containing foo and then a character that is not a number, I would use /foo[^0-9]/. However, let's say I want to change all strings matching that pattern to foobar and then the original characters, how would I go about that?
str = foozip;
newStr = str.replace(/foo[^0-9]/, "foobar");
console.log(newStr);
//returns foobarip Note the lack of a z.
str = foozip;
newStr = str.replace(/foo/, "foobar");
console.log(newStr);
//this matches foo6zip, which is no good
Do I have to run a separate check to do this? Is there a way to carry unknown characters from one side of a replace to the other?

You have two options:
Use lookahead:
str.replace(/foo(?=[^0-9])/, "foobar")
Use capture groups:
str.replace(/foo([^0-9])/, "foobar$1")

Related

Get string between “-”

I have this string: 2015-07-023. I want to get 07 from this string.
I used RegExp like this
var regExp = /\(([^)]+-)\)/;
var matches = regExp.exec(id);
console.log(matches);
But I get null as output.
Any idea is appreciated on how to properly configure the RegExp.
The best way to do it is to not use RegEx at all, you can use regular JavaScript string methods:
var id_parts = id.split('-');
alert(id_parts[1]);
JavaScript string methods is often better than RegEx because it is faster, and it is more straight-forward and readable. Any programmer can read this code and quickly know that is is splitting the string into parts from id, and then getting the item at index 1
If you want regex, you can use following regex. Otherwise, it's better to go with string methods as in the answer by #vihan1086.
var str = '2015-07-023';
var matches = str.match(/-(\d+)-/)[1];
document.write(matches);
Regex Explanation
-: matches - literal
(): Capturing group
\d+: Matches one or more digits
Regex Visualization
EDIT
You can also use substr as follow, if the length of the required substring is fixed.
var str = '2015-07-023';
var newStr = str.substr(str.indexOf('-') + 1, 2);
document.write(newStr);
You may try the below positive lookahead based regex.
var string = "2015-07-02";
alert(string.match(/[^-]+(?=-[^-]*$)/))

regex to get last of repetition

I have the below two strings. In both cases, I am trying to retrieve "foreclosure_defenses".
str = "client_profile[lead_profile_attributes][foreclosure_defenses_attributes][0][own_property]"
str2 = "client_profile[foreclosure_defenses_attributes][0][own_property]"
I'm close but I can't get a regex that will work with both of them.
This regex works for str2, but not for str:
regex = /\w+(?:\[(\w+)_attributes\]+)\[\d+\]\[own_property\]/g
regex.exec(str2)
["client_profile[foreclosure_defenses_attributes][0][own_property]", "foreclosure_defenses"]
This regex works for str, but not for str2:
regex = /\w+(?:\[(\w+)_attributes\]?)+\[\d+\]\[own_property\]/g
regex.exec(str);
["client_profile[lead_profile_attributes][foreclosure_defenses_attributes][0][own_property]", "foreclosure_defenses"]
The last one should work for both cases, but doesn't. It should look for one or many _attributes patterns and grab the last one.
What am I doing wrong?
I think you want
/\w+(?:\[(\w+)_attributes\])+\[\d+\]\[own_property\]/
Note that if you use global g flag and you attempt to match multiple strings, you will need to reset the index of the regex.
Why not just use this:
/.+?\[(foreclosure_defenses)_attributes\]/g
Demo

Regex trying to match characters before and after symbol

I'm trying to match characters before and after a symbol, in a string.
string: budgets-closed
To match the characters before the sign -, I do: ^[a-z]+
And to match the other characters, I try: \-(\w+) but, the problem is that my result is: -closed instead of closed.
Any ideas, how to fix it?
Update
This is the piece of code, where I was trying to apply the regex http://jsfiddle.net/trDFh/1/
I repeat: It's not that I don't want to use split; it's just I was really curious, and wanted to see, how can it be done the regex way. Hacking into things spirit
Update2
Well, using substring is a solution as well: http://jsfiddle.net/trDFh/2/ and is the one I chosed to use, since the if in question, is actually an else if in a more complex if syntax, and the chosen solutions seems to be the most fitted for now.
Use exec():
var result=/([^-]+)-([^-]+)/.exec(string);
result is an array, with result[1] being the first captured string and result[2] being the second captured string.
Live demo: http://jsfiddle.net/Pqntk/
I think you'll have to match that. You can use grouping to get what you need, though.
var str = 'budgets-closed';
var matches = str.match( /([a-z]+)-([a-z]+)/ );
var before = matches[1];
var after = matches[2];
For that specific string, you could also use
var str = 'budgets-closed';
var before = str.match( /^\b[a-z]+/ )[0];
var after = str.match( /\b[a-z]+$/ )[0];
I'm sure there are better ways, but the above methods do work.
If the symbol is specifically -, then this should work:
\b([^-]+)-([^-]+)\b
You match a boundry, any "not -" characters, a - and then more "not -" characters until the next word boundry.
Also, there is no need to escape a hyphen, it only holds special properties when between two other characters inside a character class.
edit: And here is a jsfiddle that demonstrates it does work.

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,"");

How to put variable in regular expression match?

I have the following snippet. I want to find the appearance of a, but it does not work. How can I put the variable right?
var string1 = 'asdgghjajakhakhdsadsafdgawerwweadf';
var string2 = 'a';
string1.match('/' + string2 + '/g').length;
You need to use the RegExp constructor instead of a regex literal.
var string = 'asdgghjjkhkh';
var string2 = 'a';
var regex = new RegExp( string2, 'g' );
string.match(regex);
If you didn't need the global modifier, then you could just pass string2, and .match() will create the regex for you.
string.match( string2 );
If you are merely looking to check whether a string contains another string, then your best bet is simply to use match() without a regex.
You may object: But I need a regex to check for classes, like \s, to define complicated patterns, etc..
In that case: You will need change the syntax even more, double-escaping your classes and dropping starting/ending / regex indicator symbols.
Imagine this regex...
someString.match(/\bcool|tubular\b);
The exact equivalent of this, when using a new new RegExp(), is...
someStringRegex = new RegExp('\\bcool|tubular\\b');
Two things happened in this transition:
Drop the opening and closing / (otherwise, your regex will fail).
Double escape your character classes, like \b becomes \\b for word borders, and \w becomes \\w for whitespace, etc. (otherwise, your regex will fail).
Here is another example-
//confirm whether a string contains target at its end (both are variables in the function below, e.g. confirm whether str "Abstraction" contains target "action" at the end).
function confirmEnding(string, target) {
let regex = new RegExp(target);
return regex.test(string);
};

Categories