Why is my JavaScript output weird when I am implementing .match regex? - javascript

So, i been getting this kind of output lately when im coding but i just want to make sure its normal or maybe im doing something wrong. Here is a simple code.. maybe it has to do with regex.
my console says " (1) ['a', index: 1, input: 'karina', groups: undefined] "
function reg(s) {
reg = /[aeiou]/;
console.log(s.match(reg));
}
reg("turtle");

Your code is working just fine. The .match() method will compare the string and the RegEx that you defined and return an array with the first match it finds and at what index it happens.
If you want to get back an array with all of the results and without the other information, all you need to do is add a "g" at the end of your RegEx. Your function should look like this:
function reg(s) {
reg = /[aeiou]/g;
console.log(s.match(reg));
}
reg('turtle');
The "g" at the end, will make so that .match() will look and grab all of the occurrences in the string that you are checking, instead of just the first one.

Related

Test fails when I include an array reference in regex (array with index in regex) JavaScript

I am doing a challenge on freeCodeCamp. I am passed an array with 2 strings, the instructions are to test to see if the letters in the second string are in the first string.
Here's what I have:
return /[arr\[1\]]/gi.test(arr[0]);
This passes all the tests except where it tries to match with a capital letter.
mutation(["hello", "Hello"]) should return true.
It's the only test that fails, I have tested my regex on regexr.com with:
/[Hello]/gi and it matches with 'hello'.
Yes, there are other ways to do it, but why does it fail when I pass the string into the regex from the array?
EDIT: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-algorithm-scripting/mutations
keep in mind that with this: return /[arr\[1\]]/gi.test(arr[0]) you are evaluating exactly this string "arr[1]". test() is a method of RegExp, then to add variables in a regex, or build the regex as string, you should use the RegExp constructor. Like the example below.
See this for browser compatibility of flags.
function mutation(str){
var r = new RegExp(str[0].toLowerCase(), "gi")
return r.test(str[1].toLowerCase());
}
console.log(mutation(["hello", "Hello"]))
The fact that your code passes the test for ["Mary", "Army"] shows that the problem is not one of case sensitivity. The only reason your code passes any of the tests is that /[arr\[1\]]/ looks for matches against the set of characters ar1[] which coincidentally happens to correctly match 8 of the 9 tests. Anyway the other - perhaps biggest - issue is that you are not testing all of the characters in arr[1] against arr[0]; if you run #Emeeus's answer it returns false positives for many of the tests. So, to test all of the characters in arr[1] against arr[0] you need something like this:
function mutation(arr) {
return arr[1].split('').reduce((t, c) => t && new RegExp(c, 'i').test(arr[0]), true);
}
let tests = [
['hello', 'hey'],
["hello", "Hello"],
["zyxwvutsrqponmlkjihgfedcba", "qrstu"],
["Mary", "Army"],
["Mary", "Aarmy"],
["Alien", "line"],
["floor", "for"],
["hello", "neo"],
["voodoo", "no"]
];
tests.map(arr => console.log(arr[0] + ", " + arr[1] + " => " + (mutation(arr) ? 'match' : 'no match')));
JavaScript has a special syntax for Regular Expressions. Those two lines are essentially the same:
return /[arr\[1\]]/gi.test(arr[0]);
return new RegExp('[arr\\[1\\]]', 'gi').test(arr[0]);
but what you probably want is this:
new RegExp('['+arr[1]+']', 'gi').test(arr[0]);
However, you should be careful since this approach does not work if it contains special characters such as '[' or ']'.
Whenever you have a javascript variable in a regular expression, you should construct a new RegExp object. Taken from your question, it should look like this
return new RegExp(arr[1], "gi").test(arr[0]);
As one hint on freeCodeCamp.org says, you can solve the problem easier if you transform the strings into arrays, using the spread operator. No need for regular expressions.
Instead of:
return /[arr\[1\]]/gi.test(arr[0]);
you can do:
return new RegEx(arr[1], gi);
Your code uses a character match ([ ]), not a string match, so it will match anything, that has those characters directly (That's why uppercase and lowercase differs, although you have specified 'i').
The new expression directly uses the string to match, not just the characters.

I need match string in quotes

I need to match string within "" , I'm using following it's not working
var str='"hi" hello "abc\nddk" ef "gh"';
console.log(str.match(/(?=")[^"]*?(?=")/));
t's giving me output as
[]
I need output as
["hi", "abc\nddk", "gh"]
Update :
I can use regex "[^"]" to match string in quotes but I need to avoid the " from the result
Simplest way would be to do:
/"[^"]*?"/g
This will return an array with "hi", "abc\nddk" and "gh" and you can do something like piece.replace(/"/g, "") on individual pieces to get rid of the ". If you don't like that then rather than do a match you can do a search and don't replace
var matches = [];
str.replace(/"([^"]*?)"/g, function (_, match) {
matches.push(match);
});
This should do the trick:
/(?| (")((?:\\"|[^"])+)\1 | (')((?:\\'|[^'])+)\1 )/xg
Demo
BTW: regex101.com is a great resource to use (which is where I got the regex above)
Update
The first one I posted works for PHP, here is one for JS
/"([^"\\]*(?:\\.[^"\\]*)*)"|\w+|'([^'\\]*(?:\\.[^'\\]*)*)'/g
Maybe I read your question incorrectly but this is working for me
/\".+\"/gm
https://regex101.com/r/wF0yN4/1

JS / RegEx to remove characters grouped within square braces

I hope I can explain myself clearly here and that this is not too much of a specific issue.
I am working on some javascript that needs to take a string, find instances of chars between square brackets, store any returned results and then remove them from the original string.
My code so far is as follows:
parseLine : function(raw)
{
var arr = [];
var regex = /\[(.*?)]/g;
var arr;
while((arr = regex.exec(raw)) !== null)
{
console.log(" ", arr);
arr.push(arr[1]);
raw = raw.replace(/\[(.*?)]/, "");
console.log(" ", raw);
}
return {results:arr, text:raw};
}
This seems to work in most cases. If I pass in the string [id1]It [someChar]found [a#]an [id2]excellent [aa]match then it returns all the chars from within the square brackets and the original string with the bracketed groups removed.
The problem arises when I use the string [id1]It [someChar]found [a#]a [aa]match.
It seems to fail when only a single letter (and space?) follows a bracketed group and starts missing groups as you can see in the log if you try it out. It also freaks out if i use groups back to back like [a][b] which I will need to do.
I'm guessing this is my RegEx - begged and borrowed from various posts here as I know nothing about it really - but I've had no luck fixing it and could use some help if anyone has any to offer. A fix would be great but more than that an explanation of what is actually going on behind the scenes would be awesome.
Thanks in advance all.
You could use the replace method with a function to simplify the code and run the regexp only once:
function parseLine(raw) {
var results = [];
var parsed = raw.replace(/\[(.*?)\]/g, function(match,capture) {
results.push(capture);
return '';
});
return { results : results, text : parsed };
}
The problem is due to the lastIndex property of the regex /\[(.*?)]/g; not resetting, since the regex is declared as global. When the regex has global flag g on, lastIndex property of RegExp is used to mark the position to start the next attempt to search for a match, and it is expected that the same string is fed to the RegExp.exec() function (explicitly, or implicitly via RegExp.test() for example) until no more match can be found. Either that, or you reset the lastIndex to 0 before feeding in a new input.
Since your code is reassigning the variable raw on every loop, you are using the wrong lastIndex to attempt the next match.
The problem will be solved when you remove g flag from your regex. Or you could use the solution proposed by Tibos where you supply a function to String.replace() function to do replacement and extract the capturing group at the same time.
You need to escape the last bracket: \[(.*?)\].

Replace .split() with .match() using regex in javascript

I'm having difficulties with constructing some regular expressions using Javascript.
What I need:
I have a string like: Woman|{Man|Boy} or {Girl|Woman}|Man or Woman|Man etc.
I need to split this string by '|' separator, but I don't want it to be split inside curly brackets.
Examples of strings and desired results:
// Expample 1
string: 'Woman|{Man|Boy}'
result: [0] = 'Woman', [1] = '{Man|Boy}'
// Example 2
string '{Woman|Girl}|{Man|Boy}'
result: [0] = '{Woman|Girl}', [1] = '{Man|Boy}'
I can't change "|" symbol to another inside the brackets because the given strings are the result of a recursive function. For example, the original string could be
'Nature|Computers|{{Girls|Women}|{Boys|Men}}'
try this:
var reg=/\|(?![^{}]+})/g;
Example results:
var a = 'Woman|{Man|Boy}';
var b = '{Woman|Girl}|{Man|Boy}';
a.split(reg)
["Woman", "{Man|Boy}"]
b.split(reg)
["{Woman|Girl}", "{Man|Boy}"]
for your another question:
"Now I have another, but a bit similar problem. I need to parse all containers from the string. Syntax of the each container is {sometrash}. The problem is that container can contain another containers, but I need to parse only "the most relative" container. mystring.match(/\{+.+?\}+/gi); which I use doesn't work correctly. Could you correct this regex, please? "
you can use this regex:
var reg=/\{[^{}]+\}/g;
Example results:
var a = 'Nature|Computers|{{Girls|Women}|{Boys|Men}}';
a.match(reg)
["{Girls|Women}", "{Boys|Men}"]
You can use
.match(/[^|]+|\{[^}]*\}/g)
to match those. However, if you have a nesting of arbitrary depth then you'll need to use a parser, [javascript] regex won't be capable of doing that.
Test this:
([a-zA-Z0-9]*\|[a-zA-Z0-9]*)|{[a-zA-Z0-9]*\|[a-zA-Z0-9]*}

Javascript RegExp matching returning too many

I need to take a string and get some values from it. I have this string:
'tab/tab2/tab3'
The '/tab3' is optional so this string should also work:
'tab/tab2'
I currently am trying this which works for the most part:
'tab/tab2/tab3'.match(new RegExp('^tab/([%a-zA-Z0-9\-\_\s,]+)(/([%a-zA-Z0-9-_s,]+)?)$'));
This will return:
["tab/tab2/tab3", "tab2", "/tab3", "tab3"]
but I want it to return
["tab/tab2/tab3", "tab2", "tab3"]
So I need to get rid of the 3rd index item ("/tab3") and also get it to work with just the 'tab/tab2' string.
To complicate it even more, I only have control over the /([%a-zA-Z0-9-_s,]+)? part in the last grouping meaning it will always wrap in a grouping.
you don't need regex for this, just use split() method:
var str = 'tab/tab2/tab3';
var arr = str.split('/');
console.log(arr[0]); //tab
console.log(arr[1]); //tab2
jsfiddle
I used this regexp to do this:
'tab/tab2/tab3'.match(new RegExp('^tab/([%a-zA-Z0-9\-\_\s,]+)(?:/)([%a-zA-Z0-9-_s,]+)$'));
Now I get this return
["tab/tab2/tab3", "tab2", "tab3"]
Now I just need to allow 'tab/tab2' to be accepted aswell...
Do not put regex between " or ', using /g to make global search else only first occurrence is returned
"tab/tab2/tab3".match(/tab[0-9]/g)

Categories

Resources