Validation of price in Javascript using Regex - javascript

I need to check whether a string is valid price or not. In some locales, "." is interchanged with "," and separator could be at thousands or hundreds.
For Example:
Valid:
1234
1,234
1.234
1,23,334
1.23.334
1,23,334.00
1.23.334,00
Invalid:
1,23...233
1,,23
etc
The Regex I have used is
/(\d+(?:[\.,](?![\.,])\d+)*)/g
but this is giving me two matches for "1,23...233" i,e "1,23" and "233" as matches, I don't want to return any matches for that. Here is the regex I have been working on. What I actually want to do, whenever there is "." or "," next character should not be "." or "," and it should be a digit.

You can simply do this.
^\d+(?:[.,]\d+)*$
Try this.See demo.
https://regex101.com/r/tX2bH4/61
var re = /^\d+(?:[.,]\d+)*$/gm;
var str = '1234\n1,234\n1.234\n1,23,334\n1.23.334\n1,23,334.00\n1.23.334,00\n1,23...233\n1,23.';
var m;
while ((m = re.exec(str)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}

Seems like you want something like this,
^\d+(?:\.\d+)?(?:,\d+(?:\.\d+)?)*$
DEMO
OR
^(?!.*(,,|,\.|\.,|\.\.))[\d.,]+$
Negative lookahead at the start asserts that the sting won't contain consecutive commas or dots or dots and commas.
DEMO

Related

Excluding matcher [duplicate]

After coming to the shocking realization that regular expressions in JavaScript are somewhat different from the ones in PCE, I am stuck with the following.
In php I extract a number after x:
(?x)[0-9]+
In JavaScript the same regex doesn't work, due to invalid group resulting from the capturing parenthesis difference.
So I am trying to achieve the same trivial functionality, but I keep getting both the x and the number:
(?:x)([0-9]+)
How do I capture the number after x without including x?
This works too:
/(?:x)([0-9]+)/.test('YOUR_STRING');
Then, the value you want is:
RegExp.$1 // group 1
You can try the following regex: (?!x)[0-9]+
fiddle here: https://jsfiddle.net/xy6x938e/1/
This is assuming that you are now looking for an x followed by a number, it uses a capture group to capture just the numbers section.
var myString = "x12345";
var myRegexp = /x([0-9]+)/g;
var match = myRegexp.exec(myString);
var myString2 = "z12345";
var match2 = myRegexp.exec(myString2);
if(match != null && match.length > 1){
alert('match1:' + match[1]);
}
else{
alert('no match 1');
}
if(match2 != null && match2.length > 1){
alert('match2:' + match2[1]);
}
else{
alert('no match 2');
}
(\d+) try this!
i have tested on this tool with x12345
http://www.regular-expressions.info/javascriptexample.html
How do I capture the number after x without including x?
In fact, you just want to extract a sequence of digits after a fixed string/known pattern.
Your PCRE (PHP) regex, (?x)[0-9]+, is wrong becaue (?x) is an inline version of a PCRE_EXTENDED VERBOSE/COMMENTS flag (see "Pattern Modifiers"). It does not do anything meaningful in this case, (?x)[0-9]+ is equal to [0-9]+ or \d+.
You can use
console.log("x15 x25".match(/(?<=x)\d+/g));
You can also use a capturing group and then extract Group 1 value after a match is obtained:
const match = /x(\d+)/.exec("x15");
if (match) {
console.log(match[1]); // Getting the first match
}
// All matches
const matches = Array.from("x15,x25".matchAll(/x(\d+)/g), x=>x[1]);
console.log(matches);
You still can use exclusive pattern (?!...)
So, for your example it will be /(?!x)[0-9]+/. Give a try to the following:
/(?!x)\d+/.exec('x123')
// => ["123"]

javascript - regexp exec internal index doesn't progress if first char is not a match

I need to match numbers that are not preceeded by "/" in a group.
In order to do this I made the following regex:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
First part matches start of the string and anything else except "/", second part matches a number. Everything works ok regarding the regex (it matches what I need). I use https://regex101.com/ for testing. Example here: https://regex101.com/r/7UwEUn/1
The problem is that when I use it in js (script below) it goes into an infinite loop if first character of the string is not a number. At a closer look it seems to keep matching the start of the string, never progressing further.
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
var text = "a 1 b";
while (match = reg.exec(text)) {
if (typeof match[2] != 'undefined' && match[2] != '') {
numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
}
If the string starts with a number ("1 a b") all is fine.
The problem appears to be here (^|[^,/]) - removing ^| will fix the issue with infinite loop but it will not match what I need in strings starting with numbers.
Any idea why the internal index is not progressing?
Infinite loop is caused by the fact your regex can match an empty string. You are not likely to need empty strings (even judging by your code), so make it match at least one digit, replace the last * with +:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]+)/g;
var text = "a 1 b a 2 ana 1/2 are mere (55";
var numbers=[];
while (match = reg.exec(text)) {
numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
console.log(numbers);
Note that this regex will not match numbers like 34. and in that case you may use /(^|[^,\/])([0-9]*\.?[0-9]+|[0-9]*\.)/g, see this regex demo.
Alternatively, you may use another "trick", advance the regex lastIndex manually upon no match:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]+)/g;
var text = "a 1 b a 2 ana 1/2 are mere (55";
var numbers=[];
while (match = reg.exec(text)) {
if (match.index === reg.lastIndex) {
reg.lastIndex++;
}
if (match[2]) numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
console.log(numbers);

JavaScript regex get number after string

After coming to the shocking realization that regular expressions in JavaScript are somewhat different from the ones in PCE, I am stuck with the following.
In php I extract a number after x:
(?x)[0-9]+
In JavaScript the same regex doesn't work, due to invalid group resulting from the capturing parenthesis difference.
So I am trying to achieve the same trivial functionality, but I keep getting both the x and the number:
(?:x)([0-9]+)
How do I capture the number after x without including x?
This works too:
/(?:x)([0-9]+)/.test('YOUR_STRING');
Then, the value you want is:
RegExp.$1 // group 1
You can try the following regex: (?!x)[0-9]+
fiddle here: https://jsfiddle.net/xy6x938e/1/
This is assuming that you are now looking for an x followed by a number, it uses a capture group to capture just the numbers section.
var myString = "x12345";
var myRegexp = /x([0-9]+)/g;
var match = myRegexp.exec(myString);
var myString2 = "z12345";
var match2 = myRegexp.exec(myString2);
if(match != null && match.length > 1){
alert('match1:' + match[1]);
}
else{
alert('no match 1');
}
if(match2 != null && match2.length > 1){
alert('match2:' + match2[1]);
}
else{
alert('no match 2');
}
(\d+) try this!
i have tested on this tool with x12345
http://www.regular-expressions.info/javascriptexample.html
How do I capture the number after x without including x?
In fact, you just want to extract a sequence of digits after a fixed string/known pattern.
Your PCRE (PHP) regex, (?x)[0-9]+, is wrong becaue (?x) is an inline version of a PCRE_EXTENDED VERBOSE/COMMENTS flag (see "Pattern Modifiers"). It does not do anything meaningful in this case, (?x)[0-9]+ is equal to [0-9]+ or \d+.
You can use
console.log("x15 x25".match(/(?<=x)\d+/g));
You can also use a capturing group and then extract Group 1 value after a match is obtained:
const match = /x(\d+)/.exec("x15");
if (match) {
console.log(match[1]); // Getting the first match
}
// All matches
const matches = Array.from("x15,x25".matchAll(/x(\d+)/g), x=>x[1]);
console.log(matches);
You still can use exclusive pattern (?!...)
So, for your example it will be /(?!x)[0-9]+/. Give a try to the following:
/(?!x)\d+/.exec('x123')
// => ["123"]

selecting with regex content between two points

I always have a hard time with regex..
I'm trying to select the text between (taking into acount the before and after)
'window.API=' and ';' //for window.API= '--API--';
and other cases like:
'window.img_cdn=' and ';' //for window.img_cdn= '--imgCDN--';
any tips on witch regex concepts I should use would be a great help!
If you want to capture the content between 'xx' you can use a regex like this:
'(.*?)'
working demo
For the sample text:
window.API= '--API--';
window.img_cdn= '--imgCDN--';
You will capture:
MATCH 1
1. [13-20] `--API--`
MATCH 2
1. [40-50] `--imgCDN--`
The javascript code you can use is:
var re = /'(.*?)'/g;
var str = 'window.API= \'--API--\';\nwindow.img_cdn= \'--imgCDN--\';';
var m;
while ((m = re.exec(str)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
On the other hand, if you specifically want to capture the content for only those entries, then you can use this regex:
window\.(?:API|img_cdn).*?'(.*?)'
If you want to match any text between a <some string>= sign and a semicolon, here you go:
(?:[\w\.]+\s*=\s')(.+)(?:';)$
This regex pattern will match a full string if an escaped apostrophe is present in the string: //for window.img_cdn = '--imgCDN and \'semicolon\'--';
JavaScript code:
var re = /(?:[\w\.]+\s*=\s')(.+)(?:';)$/gm;
var str = '//for window.img_cdn= \'--imgCDN--\';\n//for window.img_cdn = \'--imgCDN and semicolon = ;;;--\';';
var m;
while ((m = re.exec(str)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// view results
}
The required text is in the 1st captured group. In case there is a semicolon in the text you are looking for, you will correctly match it due to the $ anchor.
See demo here

Cannot get all possible overlapping regular expression matches

I have string
Started: 11.11.2014 11:19:28.376<br/>Ended: 1.1.4<br/>1:9:8.378<br/>Request took: 0:0:0.2
I need to add zeros in case I encounter 1:1:8 it should be 01:01:08 same goes for date. I tried using
/((:|\.|\s)[0-9](:|\.))/g
but it did not give all possible overlapping matches. How to fix it?
var str = "Started: 11.11.2014 11:19:28.376<br/>Ended: 11.11.2014<br/>11:19:28.378<br/>Request took: 0:0:0.2";
var re = /((:|\.|\s)[0-9](:|\.))/g
while ((match = re.exec(str)) != null) {
//alert("match found at " + match.index);
str = [str.slice(0,match.index), '0', str.slice(match.index+1,str.length)];
}
alert(str);
This will probably do what you want:
str.replace(/\b\d\b/g, "0$&")
It searches for lone digits \d, and pad 0 in front.
The first word boundary \b checks that there is no [a-zA-Z0-9_] in front, and the second checks there is no [a-zA-Z0-9_] behind the digit.
$& in the replacement string refers to the whole match.
If you want to pad 0 as long as the character before and after are not digits:
str.replace(/(^|\D)(\d)(?!\d)/g, "$10$2")

Categories