Javascript Regular Expression (x) - javascript

I have a piece of code as follows:
var str = "foo xxx eee dsds";
var regex = /(foo)/;
console.log(str.match(regex));
I expected output is:
foo
But the actual output is:
foo, foo
If i declare:
var regex = /(foo)/g;
The output only is foo
Can anyone help me? Thank for your help.

The second value in the array is the captured value, in absence of global modifiers match results contains the captured values. If you are removed the capturing group the result will only contains the match.
var str = "foo xxx eee dsds";
console.log(str.match(/(foo)/));
console.log(str.match(/(foo)/g));
console.log(str.match(/foo/));
Check MDN documentation :
If the regular expression does not include the g flag, returns the same result as RegExp.exec(). The returned Array has an extra input property, which contains the original string that was parsed. In addition, it has an index property, which represents the zero-based index of the match in the string.
If the regular expression includes the g flag, the method returns an Array containing all matched substrings rather than match objects. Captured groups are not returned. If there were no matches, the method returns null.

Your output is a return value of the match method which is an array. To get the desired output, use either str.match(regex)[0] (the whole matched string) or str.match(regex)[1] (the captured substring matching (foo) which is the same in your case). But it's better to save the match array first and check if it is null or not (if the string doesn't match, it is null and null[0] will cause an error):
var match = str.match(regex);
if(match)
console.log(match[0]);
else
// do whatever you want when there's no match

Related

Empty value if regex match not found JavaScript

I'm attempting to extract any text characters at the beginning, and the following two numbers of a string. If the string starts with a number, I'd like to get an empty string value instead so the resulting array still contains 3 values.
String:
'M2.55X.45'
Code:
'M2.55X.45'.match(/(^[a-zA-Z]+)|((\.)?\d+[\/\d. ]*|\d)/g)
Expected:
["M", "2.55", ".45"]
Actual (correct):
["M", "2.55", ".45"]
String:
'2.55X.45'
Code:
'2.55X.45'.match(/(^[a-zA-Z]+)|((\.)?\d+[\/\d. ]*|\d)/g)
Expected:
["", "2.55", ".45"]
Actual:
["2.55", ".45"]
Use /^([a-zA-Z]?)(\d*(?:\.\d+)?)[a-zA-Z](\d*(?:\.\d+)?)$/.exec("2.55X.45") instead. This returns an array where the 1st element is the entire match, so you must access groups 1-indexed, for example, match[1] for the 1st value. You can try this out here.
Your current regex uses an alternate clause (|), which creates different types of grouping depending on which alternate is matched.
Here's an example (cleaned up a bit) that creates explicit groups and makes the individual groups optional.
const regex = /^([a-zA-Z]*)?(\d*(?:\.\d+)?)([a-zA-Z]+)(\d*(?:\.\d+)?)$/
console.log(regex.exec("2.55X.45"))
console.log(regex.exec("M2.55X.45"))
Note that I've removed the g flag, so the regex's state isn't preserved.
I've also used exec instead of match to not discard capture groups.
You can try this pattern
(\D*)(\d+(?:\.\d+))\D+(\.\d+)
let finder = (str) => {
return (str.match(/^(\D*)(\d+(?:\.\d+))\D+(\.\d+)/) || []).slice(1)
}
console.log(finder('M2.55X.45'))
console.log(finder("2.55X.45"))

Regular Expression, Get Sub Pattern

Why am I not able to grab the subpattern? The console displays undefined when I am expecting hello to be output. If I change matches[1] to matches[0] I get {{hello}}. So, Why can I not access the subpattern?
var str = "{{hello}}";
var matches = str.match(/{{(.+)}}/ig);
console.log(matches[1]);
Try:
str.match(/{{(.+)}}/i);
instead.
It seems like you're looking for the behavior of RegExp.exec. MDN states this:
If the regular expression does not include the g flag, returns the same result as regexp.exec(string). ...
If the regular expression includes the g flag, the method returns an Array containing all matches.
Since you had the g flag, the RegExp was trying to find all global matches (basically ignoring your groupings), returning ['{{hello}}'].
If you remove the the g flag (or alternatively use /{{(.+)}}/i.exec(str), you can get your groupings returned.

String split returns an array with more elements than expected (empty elements)

I don't understand this behaviour:
var string = 'a,b,c,d,e:10.';
var array = string.split ('.');
I expect this:
console.log (array); // ['a,b,c,d,e:10']
console.log (array.length); // 1
but I get this:
console.log (array); // ['a,b,c,d,e:10', '']
console.log (array.length); // 2
Why two elements are returned instead of one? How does split work?
Is there another way to do this?
You could add a filter to exclude the empty string.
var string = 'a,b,c,d,e:10.';
var array = string.split ('.').filter(function(el) {return el.length != 0});
A slightly easier version of #xdazz version for excluding empty strings (using ES6 arrow function):
var array = string.split('.').filter(x => x);
This is the correct and expected behavior. Given that you've included the separator in the string, the split function (simplified) takes the part to the left of the separator ("a,b,c,d,e:10") as the first element and the part to the rest of the separator (an empty string) as the second element.
If you're really curious about how split() works, you can check out pages 148 and 149 of the ECMA spec (ECMA 262) at http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
Use String.split() method with Array.filter() method.
var string = 'a,b,c,d,e:10.';
var array = string.split ('.').filter(item => item);
console.log(array); // [a,b,c,d,e:10]
console.log (array.length); // 1
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/split
trim the trailing period first
'a,b,c,d,e:10.'.replace(/\.$/g,''); // gives "a,b,c,d,e:10"
then split the string
var array = 'a,b,c,d,e:10.'.replace(/\.$/g,'').split('.');
console.log (array.length); // 1
That's because the string ends with the . character - the second item of the array is empty.
If the string won't contain . at all, you will have the desired one item array.
The split() method works like this as far as I can explain in simple words:
Look for the given string to split by in the given string. If not found, return one item array with the whole string.
If found, iterate over the given string taking the characters between each two occurrences of the string to split by.
In case the given string starts with the string to split by, the first item of the result array will be empty.
In case the given string ends with the string to split by, the last item of the result array will be empty.
It's explained more technically here, it's pretty much the same for all browsers.
According to MDN web docs:
Note: When the string is empty, split() returns an array containing
one empty string, rather than an empty array. If the string and
separator are both empty strings, an empty array is returned.
const myString = '';
const splits = myString.split();
console.log(splits);
// ↪ [""]
Well, split does what it is made to do, it splits your string. Just that the second part of the split is empty.
Because your string is composed of 2 part :
1 : a,b,c,d,e:10
2 : empty
If you try without the dot at the end :
var string = 'a,b,c:10';
var array = string.split ('.');
output is :
["a,b,c:10"]
You have a string with one "." in it and when you use string.split('.') you receive array containing first element with the string content before "." character and the second element with the content of the string after the "." - which is in this case empty string.
So, this behavior is normal. What did you want to achieve by using this string.split?
try this
javascript gives two arrays by split function, then
var Val = "abc#gmail.com";
var mail = Val.split('#');
if(mail[0] && mail[1]) { alert('valid'); }
else { alert('Enter valid email id'); valid=0; }
if both array contains length greater than 0 then condition will true

Regex to extract substring, returning 2 results for some reason

I need to do a lot of regex things in javascript but am having some issues with the syntax and I can't seem to find a definitive resource on this.. for some reason when I do:
var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test)
it shows
"afskfsd33j, fskfsd33"
I'm not sure why its giving this output of original and the matched string, I am wondering how I can get it to just give the match (essentially extracting the part I want from the original string)
Thanks for any advice
match returns an array.
The default string representation of an array in JavaScript is the elements of the array separated by commas. In this case the desired result is in the second element of the array:
var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test[1]);
Each group defined by parenthesis () is captured during processing and each captured group content is pushed into result array in same order as groups within pattern starts. See more on http://www.regular-expressions.info/brackets.html and http://www.regular-expressions.info/refcapture.html (choose right language to see supported features)
var source = "afskfsd33j"
var result = source.match(/a(.*)j/);
result: ["afskfsd33j", "fskfsd33"]
The reason why you received this exact result is following:
First value in array is the first found string which confirms the entire pattern. So it should definitely start with "a" followed by any number of any characters and ends with first "j" char after starting "a".
Second value in array is captured group defined by parenthesis. In your case group contain entire pattern match without content defined outside parenthesis, so exactly "fskfsd33".
If you want to get rid of second value in array you may define pattern like this:
/a(?:.*)j/
where "?:" means that group of chars which match the content in parenthesis will not be part of resulting array.
Other options might be in this simple case to write pattern without any group because it is not necessary to use group at all:
/a.*j/
If you want to just check whether source text matches the pattern and does not care about which text it found than you may try:
var result = /a.*j/.test(source);
The result should return then only true|false values. For more info see http://www.javascriptkit.com/javatutors/re3.shtml
I think your problem is that the match method is returning an array. The 0th item in the array is the original string, the 1st thru nth items correspond to the 1st through nth matched parenthesised items. Your "alert()" call is showing the entire array.
Just get rid of the parenthesis and that will give you an array with one element and:
Change this line
var test = tesst.match(/a(.*)j/);
To this
var test = tesst.match(/a.*j/);
If you add parenthesis the match() function will find two match for you one for whole expression and one for the expression inside the parenthesis
Also according to developer.mozilla.org docs :
If you only want the first match found, you might want to use
RegExp.exec() instead.
You can use the below code:
RegExp(/a.*j/).exec("afskfsd33j")
I've just had the same problem.
You only get the text twice in your result if you include a match group (in brackets) and the 'g' (global) modifier.
The first item always is the first result, normally OK when using match(reg) on a short string, however when using a construct like:
while ((result = reg.exec(string)) !== null){
console.log(result);
}
the results are a little different.
Try the following code:
var regEx = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
var result = sample_string.match(regEx);
console.log(JSON.stringify(result));
// ["1 cat","2 fish"]
var reg = new RegExp('[0-9]+ (cat|fish)','g'), sampleString="1 cat and 2 fish";
while ((result = reg.exec(sampleString)) !== null) {
console.dir(JSON.stringify(result))
};
// '["1 cat","cat"]'
// '["2 fish","fish"]'
var reg = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
while ((result = reg.exec(sampleString)) !== null){
console.dir(JSON.stringify(result))
};
// '["1 cat","1 cat","cat"]'
// '["2 fish","2 fish","fish"]'
(tested on recent V8 - Chrome, Node.js)
The best answer is currently a comment which I can't upvote, so credit to #Mic.

assign matched values from jquery regex match to string variable

I am doing it wrong. I know.
I want to assign the matched text that is the result of a regex to a string var.
basically the regex is supposed to pull out anything in between two colons
so blah:xx:blahdeeblah
would result in xx
var matchedString= $(current).match('[^.:]+):(.*?):([^.:]+');
alert(matchedString);
I am looking to get this to put the xx in my matchedString variable.
I checked the jquery docs and they say that match should return an array. (string char array?)
When I run this nothing happens, No errors in the console but I tested the regex and it works outside of js. I am starting to think I am just doing the regex wrong or I am completely not getting how the match function works altogether
I checked the jquery docs and they say that match should return an array.
No such method exists for jQuery. match is a standard javascript method of a string. So using your example, this might be
var str = "blah:xx:blahdeeblah";
var matchedString = str.match(/([^.:]+):(.*?):([^.:]+)/);
alert(matchedString[2]);
// -> "xx"
However, you really don't need a regular expression for this. You can use another string method, split() to divide the string into an array of strings using a separator:
var str = "blah:xx:blahdeeblah";
var matchedString = str.split(":"); // split on the : character
alert(matchedString[1]);
// -> "xx"
String.match
String.split

Categories

Resources