I have a pattern bellow:
var patt = /((name)|(names)*)/g;
and I have a string for match:
var word = "namesnames";
word is according to pattern logicly, but word.match(patt) return :
["name", "", "name", "", ""]
which is wrong!
i want "namesnames" result from match,
please help me.
thanks.
The problem is that you used (names)*, meaning "names" 0 or more times, when you should have done ((name)(?:s))+, meaning "name" or "names" 1 or more times.
If I understand what you want correctly, you can make it much simpler:
var patt = /(names?)+/g;
Related
I am writing a Javascript function to convert a sentence from first person to second person. My current test function is as follows:
function statementCreator() {
var sentence = "I went to the movies with my friend, Sally. Sally says that I'm her best friend.";
var transforms = {
"I" : "YOU",
"ME" : "YOU",
"MY" : "YOUR",
"AM" : "ARE",
"MINE" : "YOURS",
"I'M" : "YOU'RE"
};
var pattern = `\\b(?:${Object.keys(transforms).join('|')})\\b`;
var re = new RegExp(pattern, "g");
str = sentence.toUpperCase().replace(re, matched => transforms[matched]);
console.log(str);
}
This creates the following regex pattern:
/\b(?:I|ME|MY|AM|MINE|I'M)\b/g
Which produces the following output:
YOU WENT TO THE MOVIES WITH YOUR FRIEND, SALLY. SALLY SAYS THAT YOU'M HER BEST FRIEND.
I'm very new to Javascript and, so, this is most probably a terrible way to do this and, of course this leaves me with the word YOU'M as part of my output as well.
But, ideally, I'd like a solution that could:
Allow for me to add new entries into the dictionary and they'd be added to the replacements (like was done here with the ${Object.keys(transforms).join('|')} portion)
Obviously, be able to deal with entries such as I'M.
What would be a good way to do this and, just in case anyone knows of a completely different way I could easily change from first to second person more easily / correctly, I'd LOVE that answer as well!!
Thanks!
Word boundaries won't give correct result because you have non-word characters like ' in I'M and since I is placed before the I'M in alternations \bI\b satisfies the match in I'm and makes it YOU'm.
To address this, you may use this solution with slightly different approach in regex i.e.
(?<!\w)(?:I|ME|MY|AM|MINE|I'M)(?![\w'])
RegEx Demo
(?<!\w): Negative Lookbehind to make sure we don't have a word character before the match
(?![\w']): Negative Lookahead to make sure we don't have a word character or ' after the match
Code:
function statementCreator() {
var sentence = "I went to the movies with my friend, Sally. Sally says that I'm her best friend. I, the current narrator, went to the movies.";
var transforms = {
"I" : "YOU",
"ME" : "YOU",
"MY" : "YOUR",
"AM" : "ARE",
"MINE" : "YOURS",
"I'M" : "YOU'RE"
};
var pattern = `(?<!\\w)(?:${Object.keys(transforms).join('|')})(?![\\w'])`;
var re = new RegExp(pattern, "ig");
str = sentence.toUpperCase().replace(re, matched => transforms[matched]);
console.log(str);
}
statementCreator();
While whitespae bounaries will work when you are sure your words are always in between whitespace chars or start/end of string, a more universal solution in this case is simply sorting your keys by length in descending order before creating the alternation pattern:
Object.keys(transforms).sort((a, b) => b.length - a.length)
This fixes the problem because the first alternative found stops the regex engine from trying the rest of the alternatives, please refer to the "Remember That The Regex Engine Is Eager".
See the JavaScript demo:
function statementCreator() {
var sentence = "I went to the movies with my friend, Sally. Sally says that I'm her best friend.";
var transforms = {
"I" : "YOU",
"ME" : "YOU",
"MY" : "YOUR",
"AM" : "ARE",
"MINE" : "YOURS",
"I'M" : "YOU'RE"
};
var keys = Object.keys(transforms).sort((a, b) => b.length - a.length);
var pattern = `\\b(?:${keys.join('|')})\\b`;
var re = new RegExp(pattern, "g");
str = sentence.toUpperCase().replace(re, matched => transforms[matched]);
console.log(str);
}
statementCreator();
Output:
YOU WENT TO THE MOVIES WITH YOUR FRIEND, SALLY. SALLY SAYS THAT YOU'RE HER BEST FRIEND.
Let's say that I have the following string taken from user input:
The ##firstvar## went to the ##secondvar## with the ##thirdvar##.
Where the values "firstvar" "secondvar" and "thirdvar" all came from user input as well, so they aren't known before runtime.
Is there a way to replace all the matches between sets of "##" with a corresponding cached variable?
Say for example I have these values cached:
cache[firstvar] = "dog"
cache[secondvar] = "river"
cache[thirdvar] = "cat"
I want the final output string to be:
The dog went to the river with the cat.
I've tried regex replace but can't figure it out when the replacements are dynamic like this.
You can replace them by using a function as second argument in String.prototype.replace().
const cache = { firstvar: "dog", secondvar: "river", thirdvar: "cat" },
text = "The ##firstvar## went to the ##secondvar## with the ##thirdvar##.",
regex = /##(.*?)##/g;
console.log( text.replace(regex, (_match, group1) => cache[group1]) );
I have a variable which contain a string and I want to return only the letters from regular expression (“b” and “D”) or any letter that I indicate on regular expression from match().
var kk = "AaBbCcDd".match(/b|D/g);
kk.forEach(function(value,index){
console.log(value,index)
});
My problem is that regular expression I think because is returning b and D but the index is not the index from kk variable and I'm not really sure, why ... so if someone can help me a little bit because I stuck
The match method from javascript only returns an array with the given match:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/match
You would need to implement a new function which will loop through all characters of your string and return the given index of the matches.
This method could use the function search from String.prototype: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/search
You have to write a new function to get the index of the matched regex like a sample below:-
var re = /bar/g,
str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
alert("match found at " + match.index);
}
Hope this will help you
Actually this is the answer :
var kk = "AaBbCcDd".match(/B?d?/g);
kk.forEach(function(value,index){
console.log(value,index)
});
if someone will encounter this scenario ...
The match() regular expresion B?d? will return an array indicating the position of "B" and "d" of the initial array kk.
I'm a total regex noob and unfortunately could find a regex to match what I need.
I'm in need of a regular expression which will return all of the characters when a number is followed by a letter.
For example: I have an array of strings [".5a", "2c#", "1e", "2f", "1.5g"] I would like to get the following array ["a", "c#", "e", "f", "g"].
This would be greatly appreciated. Thanks.
You need to use Array.prototype.map + regular expression match. Maybe something like this:
var result = [".5aD", "2c#", "1e", "2f", "1.5g"].map(function(str) {
var m = str.match(/\d(?:\.\d)?([^\d]+)/);
return m ? m[1] : null;
});
document.write(JSON.stringify( result, null, 4) );
Here you can check the explanation of the used regular expression: https://regex101.com/r/pT7oP2/1
I am trying to find a regular expression to find the occurence of certain sequence of characters inside a set of words..
Lets say if I have a set of words
["Microsoft Windows", "International Superstar", "algorithm" , "stegration stunt"]
I am trying to find the words in which character "in" has occured.. so it should return the words "Microsoft Windows", "International Superstar"
Ive tried var match = /(in)/i.exec("Microsoft Windows")
it dint do the trick.. the sequnce "in" is just an example.. it could be anyset of characters..
You can use this regex
/".*in.*"/gi
you can try this
First define your regex,
var testRegex = 'in';
then create your regex object
var myRegex = new RegExp(testRegex,"g");
then go ahead and use it like any normal regex.
note: it's case-sensitive.
<script>
var arr = ["Microsoft Windows", "International Superstar", "algorithm" , "stegration stunt"];
var i;
var res = [];
for (i=0;i<arr.length;i++) {
if(arr[i].indexOf('in') > -1){
res.push(arr[i]);
}
}
alert(res);
</script>