string.replace does not work with regex - javascript

I have this string dfdfd dsfsdfsdfsdf {{random.number}} dsfdsfsdfsdf {{bla}} and simple code that shold replace any {{...}} in a given string:
const b = template.replace(/\{{(.*)\}}/g, 'aaaa');
but nothing happened template.replace just does not work however the regex seems to be matching all {{}}
Any thougts?
UPDATE:
Just realized that my input string was wrong. Now I have all working with my original regex. However thanks to #Robo-Robok now I learned about greedy regexes and will be using his regex intstead.

Regular expressions are greedy by default. Your .* eats as much as it can, which includes the first }} pair.
Try this instead:
const b = template.replace(/\{\{.*?\}\}/g, 'aaaa');
Question mark after *, ? makes the match non-greedy.
Also two things:
It's better to escape all curly brackets. Your pattern will work well without escaping them, but it's a good idea to indicate that it's just a regular text.
Parentheses are redundant in your case, because you don't do anything with the catched string between curly braces.

Related

Combining 2 regexes, one with exact match using OR operator

I am trying to combine:
^[a-zA-Z.][a-zA-Z'\\- .]*$
with
(\W|^)first\sname(\W|$)
which should check for the exact phrase, first name, if that is correct. It should match either the first regex OR the second exact match. I tried this, but appears invalid:
^(([a-zA-Z.][a-zA-Z'\\- .]*$)|((\W|^)first\sname(\W|$))
This is in javascript btw.
Combining regular expressions generally can be done simply in the following way:
Regex1 + Regex2 = (Regex1|Regex2)
^[a-zA-Z.][a-zA-Z'\\- .]*$
+ (\W|^)first\sname(\W|$) =
(^[a-zA-Z.][a-zA-Z'\\- .]*$|(\W|^)first\sname(\W|$))
Because some SO users have a hard time understand the math analogy, here's a full word explanation.
If you have a regex with content REGEX1 and a second regex with content REGEX2 and you want to combine them in the way that was described by OP in his question, a simple way to do this without optimization is the following.
(REGEX1|REGEX2)
Where you surround both regular expressions with parenthesis and divide the two with |.
Your regex would be the following:
(^[a-zA-Z.][a-zA-Z'\\- .]*$|(\W|^)first\sname(\W|$))
Your first regex has an error in it, though, that makes it invalid. Try this instead.
(^[a-zA-Z.][a-zA-Z'\- .]*$|(\W|^)first\sname(\W|$))
You had \\ in the second character class where you wanted \
The problem is that the first regex is messed up. You don't need to double escape characters. Therefore
\\-
Will match an ascii character between \(92) and (32). Remove one of the slashes.
Reference

Regex not working as expected in JavaScript

I wrote the following regex:
(https?:\/\/)?([da-z\.-]+)\.([a-z]{2,6})(\/(\w|-)*)*\/?
Its behaviour can be seen here: http://gskinner.com/RegExr/?34b8m
I wrote the following JavaScript code:
var urlexp = new RegExp(
'^(https?:\/\/)?([da-z\.-]+)\.([a-z]{2,6})(\/(\w|-)*)*\/?$', 'gi'
);
document.write(urlexp.test("blaaa"))
And it returns true even though the regex was supposed to not allow single words as valid.
What am I doing wrong?
Your problem is that JavaScript is viewing all your escape sequences as escapes for the string. So your regex goes to memory looking like this:
^(https?://)?([da-z.-]+).([a-z]{2,6})(/(w|-)*)*/?$
Which you may notice causes a problem in the middle when what you thought was a literal period turns into a regular expressions wildcard. You can solve this in a couple ways. Using the forward slash regular expression syntax JavaScript provides:
var urlexp = /^(https?:\/\/)?([da-z\.-]+)\.([a-z]{2,6})(\/(\w|-)*)*\/?$/gi
Or by escaping your backslashes (and not your forward slashes, as you had been doing - that's exclusively for when you're using /regex/mod notation, just like you don't have to escape your single quotes in a double quoted string and vice versa):
var urlexp = new RegExp('^(https?://)?([da-z.-]+)\\.([a-z]{2,6})(/(\\w|-)*)*/?$', 'gi')
Please note the double backslash before the w - also necessary for matching word characters.
A couple notes on your regular expression itself:
[da-z.-]
d is contained in the a-z range. Unless you meant \d? In that case, the slash is important.
(/(\w|-)*)*/?
My own misgivings about the nested Kleene stars aside, you can whittle that alternation down into a character class, and drop the terminating /? entirely, as a trailing slash will be match by the group as you've given it. I'd rewrite as:
(/[\w-]*)*
Though, maybe you'd just like to catch non space characters?
(/[^/\s]*)*
Anyway, modified this way your regular expression winds up looking more like:
^(https?://)?([\da-z.-]+)\.([a-z]{2,6})(/[\w-]*)*$
Remember, if you're going to use string notation: Double EVERY backslash. If you're going to use native /regex/mod notation (which I highly recommend), escape your forward slashes.

RegExp in JavaScript, when a quantifier is part of the pattern

I have been trying to use a regexp that matches any text that is between a caret, less than and a greater than, caret.
So it would look like: ^< THE TEXT I WANT SELECTED >^
I have tried something like this, but it isn't working: ^<(.*?)>^
I'm assuming this is possible, right? I think the reason I have been having such a tough time is because the caret serves as a quantifier. Thanks for any help I get!
Update
Just so everyone knows, they following from am not i am worked
/\^<(.*?)>\^/
But, it turned out that I was getting html entities since I was getting my string by using the .innerHTML property. In other words,
> ... >
< ... <
To solve this, my regexp actually looks like this:
\^<(.*?)((.|\n)*)>\^
This includes the fact that the string in between should be any character or new line. Thanks!
You need to escape the ^ symbol since it has special meaning in a JavaScript regex.
/\^<(.*?)>\^/
In a JavaScript regex, the ^ means beginning of the string, unless the m modifier was used, in which case it means beginning of the line.
This should work:
\^<(.*?)>\^
In a regex, if you want to use a character that has a special meaning (caret, brackets, pipe, ...), you have to escape it using a backslash. For example, (\w\b)*\w\. will select a sequence of words terminated by a dot.
Careful!
If you have to pass the regex pattern as a string, i.e. there's no regex literal like in javascript or perl, you may have to use a double backslash, which the programming language will escape to a single one, which will then be processed by the regex engine.
Same regex in multiple languages:
Python:
import re
myRegex=re.compile(r"\^<(.*?)>\^") # The r before the string prevents backslash escaping
PHP:
$result=preg_match("/\\^<(.*?)>\\^/",$subject); // Notice the double backslashes here?
JavaScript:
var myRegex=/\^<(.*?)>\^/,
subject="^<blah example>^";
subject.match(myRegex);
If you tell us what programming language you're writing in, we'll be able to give you some finished code to work with.
Edit: Whoops, didn't even notice this was tagged as javascript. Then, you don't have to worry about double backslash at all.
Edit 2: \b represent a word boundary. Though I agree yours is what I would have used myself.

Figuring out Regex pattern

I am still not all that good when it comes to writing Regex patterns and am having issues with trying to figure out a search pattern for the following string:
{embed_video('RpcF9EYXZpZFBhY2tfRklOQUwuZj','575','352','video_player')}
I basically need to search a page for anything in between the hash {} marks.
I have tried this:
string = $(".content").text();
string.match("^{[\w-]}");
But its not working... any ideas on what I could be doing wrong?
Thanks for the help everybody! This is what I did to make it work:
$("div", "html, body").each(function(){
var text = $(this).text();
if(text.match("^\{.*\}$")) {
console.log("FOUND");
}
})
This should find the innermost content of curly braces (even nested ones).
string.match(/\{([^\{\}]*)\}/)[1]; // the [1] gets what is within the parentheses.
edit:
Thanks to the comments below here is a cleaner version:
string.match(/\{(.*?)\}/)[1];
One problem is the lack of a quantifier. As it stands, your regex is looking for a single \w or - character, denoted by your character class. You're probably looking for either of the following quantifiers:
[\w-]* - match 0 or more \w or - characters
[\w-]+ - match 1 or more \w or - characters
Another problem is the restrictions in the character class. [\w-] won't match (, ), ", spaces or other non-word characters that may appear. If you want to match all characters, use .. If you want to match all characters except }, use [^}] instead.
For example:
string = $(".content").text();
string.match("^{[^}]+}");
Using * would allow the content within the braces to be empty.
Side note: It looks to me like you're gearing up to eval() the code contained within the { and }. eval() is generally best avoided (if possible) for both security and performance reasons. In your case, you may be able to use this instead:
var string = $(".content").text(), fn, args;
if (string.charAt(0) == "{" && string.charAt(string.length - 1) == "}") {
fn = string.slice(1, string.indexOf("("));
args = string.slice(string.indexOf("("), string.lastIndexOf(")")).split(",");
window[fn].apply(null, args);
}
If you are using eclipse by any chance, there is a regular expression plugin with which you can play around and see how your regular expression searches your text.
I would try this
string.match("^\{.*\}$");
Search for the following regular expression:
var sRe = /\{([^\}]*)\}/g;
sText.match(sRe);
It means that you are searching for character "{" followed by any symbols but not "}" optionally and then ending with "}".
Try "\{.*?\}". But it won't handle the situation with nested curly braces. Here you can test your regexps online.
string.match("^\{(.*?)\}$")[1];
I think you need to escape the {} characters...they have special meaning in regex...

Regex replaces everything that matches any character

a[b].innerHTML=a[b].innerHTML.replace(RegExp('['+bbc[c][0]+']','ig'),bbc[c][1])
This is basically what I'm working with. It's wrapped in two loops so that should explain why it looks like what it does. Basically I want to replace something that matches '['+variable from an array+']'. I'm making a BBCode script for a free forum and no don't point me at any BBCode scripts.
The problem is that regex is replacing everything that matches any character. So, it replaces [, q, c, o, d, e, ], all with the second part of the array. (QCODE is an example BBCode being used) I don't know if it does that in a normal /regex/ with [] but it's annoying as hell. I've tried escaping the [] ('\['+v+'\]'), I've tried eval(), I've tried everything you can imagine. I need to make this thing work like it's supposed to, because everything is set up as it should be. If you know how to fix this, please answer. I'd like you to test your solution before answering though because you have no idea how many methods I've tried to make this work.
Use the right escape character:
RegExp('\\['+bbc[c][0]+'\\]','ig'),
/ is just a regular character (except in regex literals, which you're not using), the escape character is \. You also have to escape twice, once for the string literal, and once for the regex.
The reason why your code is not working is because you are using RegExp, which takes in a string for a regular expression. In this string, you need to escape the backslash escape character. The following will work:
​var str = 'Before. [qcode] After.';
alert(str.replace(RegExp('\\[qcode\\]', 'ig'), 'During.'));​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

Categories

Resources