Empty value if regex match not found JavaScript - 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"))

Related

Javascript Regular Expression (x)

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

Regular Expression to get the last word from TitleCase, camelCase

I'm trying to split a TitleCase (or camelCase) string into precisely two parts using javascript. I know I can split it into multiple parts by using the lookahead:
"StringToSplit".split(/(?=[A-Z])/);
And it will make an array ['String', 'To', 'Split']
But what I need is to break it into precisely TWO parts, to produce an array like this:
['StringTo', 'Split']
Where the second element is always the last word in the TitleCase, and the first element is everything else that precedes it.
Is this what you are looking for ?
"StringToSplit".split(/(?=[A-Z][a-z]+$)/); // ["StringTo", "Split"]
Improved based on lolol answer :
"StringToSplit".split(/(?=[A-Z][^A-Z]+$)/); // ["StringTo", "Split"]
Use it like this:
s = "StringToSplit";
last = s.replace(/^.*?([A-Z][a-z]+)(?=$)/, '$1'); // Split
first = s.replace(last, ''); // StringTo
tok = [first, last]; // ["StringTo", "Split"]
You could use
(function(){
return [this.slice(0,this.length-1).join(''), this[this.length-1]];
}).call("StringToSplit".split(/(?=[A-Z])/));
//=> ["StringTo", "Split"]
In [other] words:
create the Array using split from a String
join a slice of that Array without the last element of that
Array
add that and the last element to a final Array

Extract Fractional Number From String

I have a string that looks something like this
Hey this is my 1.20 string
I'm trying to just extract 1.20 from it.
What's the best way to do this?
I've tried something like this, but I get the value of 1.20,20 rather than just 1.20
var query = $(".query_time").html();
var matches = query.match(/\d.(\d+)/);
The result of the match function is an array, not a string. So simply take
var nb = query.match(/\d.(\d+)/)[0];
BTW, you should also escape the dot if you want to have more precise match :
var nb = query.match(/\d\.(\d+)/)[0];
or this if you want to accept commas (depends on the language) :
var nb = query.match(/\d[\.,](\d+)/)[0];
But the exact regex will be based on your exact needs, of course and to match any number (scientific notation ?) I'd suggest to have a look at more complex regex.
The value of matches is actually [ "1.20", "20" ] (which is an array). If you print it, it will get converted to a string, hence the 1.20,20.
String.match returns null or an array of matches where the first index is the fully matched part and then whichever parts you wanted. So the value you want is matches[0].
Try the following
var nb = query.match(/\d\.\d+/)[0]; // "1.20"
You need to escape . because that stands for any character.
Remove the capture group (\d+) and the second match is not returned
Add [0] index to retrieve the match

regex for nested values

I'm trying to get the numbers/stings out of a string that looks like this
"[123][456][abc]"
Also I don't want to include "[" or "]" and I want to keep the values separate.
Try this on for size.
/\[(\d+|[a-zA-Z]+)\]/
Edit:
If you can support lookahead and lookbehind
/(?<=\[)(\d+|[a-zA-Z]+)(?=\])/
Another edit:
try this in javascript
var text = "[12][34][56][bxe]";
var array = text.match(/(\d+|[a-zA-Z]+)/g);
This would be a lot easier if we knew the language. For example, in Javascript you can do:
"[123][456][abc]".split(/[\[\]]/);
and similarly in Python:
>>> import re
>>> re.split(r'[\[\]]', "[123][456][abc]")
['', '123', '', '456', '', 'abc', '']
I'm sure there are ways to do this in other languages, too.
See http://www.regular-expressions.info/javascript.html, particularly the "How to Use The JavaScript RegExp Object" section:
If you want to retrieve the part of
the string that was matched, call the
exec() function of the RegExp object
that you created, e.g.: mymatch =
myregexp.exec("subject"). This
function returns an array. The zeroth
item in the array will hold the text
that was matched by the regular
expression. The following items
contain the text matched by the
capturing parentheses in the regexp,
if any. mymatch.length indicates the
length of the match[] array, which is
one more than the number of capturing
groups in your regular expression.
mymatch.index indicates the character
position in the subject string at
which the regular expression matched.
mymatch.input keeps a copy of the
subject string.
That explains how to access individual parenthesized groups. You can use that in conjunction with a pattern like /\[(\w+)\]/g

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.

Categories

Resources