var string = 'Our Prices are $355.00 and $550, down form $999.00';
How can I get those 3 prices into an array?
The RegEx
string.match(/\$((?:\d|\,)*\.?\d+)/g) || []
That || [] is for no matches: it gives an empty array rather than null.
Matches
$99
$.99
$9.99
$9,999
$9,999.99
Explanation
/ # Start RegEx
\$ # $ (dollar sign)
( # Capturing group (this is what you’re looking for)
(?: # Non-capturing group (these numbers or commas aren’t the only thing you’re looking for)
\d # Number
| # OR
\, # , (comma)
)* # Repeat any number of times, as many times as possible
\.? # . (dot), repeated at most once, as many times as possible
\d+ # Number, repeated at least once, as many times as possible
)
/ # End RegEx
g # Match all occurances (global)
To match numbers like .99 more easily I made the second number mandatory (\d+) while making the first number (along with commas) optional (\d*). This means, technically, a string like $999 is matched with the second number (after the optional decimal point) which doesn’t matter for the result — it’s just a technicality.
A non-regex approach: split the string and filter the contents:
var arr = string.split(' ').filter(function(val) {return val.startsWith('$');});
Use match with regex as follow:
string.match(/\$\d+(\.\d+)?/g)
Regex Explanation
/ : Delimiters of regex
\$: Matches $ literal
\d+: Matches one or more digits
()?: Matches zero or more of the preceding elements
\.: Matches .
g : Matches all the possible matching characters
Demo
This will check if there is a possible decimal digits following a '$'
Related
I have a requirement where I need a regex which
should not repeat alphabet
should only contain alphabet and comma
should not start or end with comma
can contain more than 2 alphabets
example :-
A,B --- correct
A,B,C,D,E,F --- correct
D,D,A --- wrong
,B,C --- wrong
B,C, --- wrong
A,,B,C --- wrong
Can anyone help ?
Another idea with capturing and checking by use of a lookahead:
^(?:([A-Z])(?!.*?\1),?\b)+$
You can test here at regex101 if it meets your requirements.
If you don't want to match single characters, e.g. A, change the + quantifier to {2,}.
The statement of the question is incomplete in several respects. I have made the following assumptions:
Considering that D,D,A is incorrect I assume that a letter cannot be followed by a comma followed by the same letter.
The string may contain the same letter more than once as long as #1 is satisfied.
Considering that A,,B,C is incorrect I assume a comma cannot follow a comma.
Since the examples contain only capital letters I will assume that lower-case letters are not permitted (though one need only set the case-indifferent flag (i) to permit either case).
We observe that the requirements are satisfied if and only if the string begins with a capital letter and is followed by a sequence of comma-capital letter pairs, provided that no capital letter is followed by a comma followed by the same letter. We therefore can attempt to match the following regular expression.
^(?:([A-Z]),(?!\1))*[A-Z]$
Demo
The elements of the expression are as follows.
^ # match beginning of string
(?: # begin a non-capture group
([A-Z]) # match a capital letter and save to capture group 1
, # match a comma
(?!\1) # use negative lookahead to assert next character is not equal
# to the content of capture group 1
)* # end non-capture group and execute it zero or more times
[A-Z] # match a capital letter
$ # match end of string
Here is a big ugly regex solution:
var inputs = ['A,B', 'D,D,D', ',B,C', 'B,C,', 'A,,B'];
for (var i=0; i < inputs.length; ++i) {
if (/^(?!.*?([^,]+).*,\1(?:,|$))[^,]+(?:,[^,]+)*$/.test(inputs[i])) {
console.log(inputs[i] + " => VALID");
}
else {
console.log(inputs[i] + " => INVALID");
}
}
The regex has two parts to it. It uses a negative lookahead to assert that no two CSV entries ever repeat in the input. Then, it uses a straightforward pattern to match any proper CSV delimited input. Here is an explanation:
^ from the start of the input
(?!.*?([^,]+).*,\1(?:,|$)) assert that no CSV element ever repeats
[^,]+ then match a CSV element
(?:,[^,]+)* followed by comma and another element, 0 or more times
$ end of the input
This one could suit your needs:
^(?!,)(?!.*,,)(?!.*(\b[A-Z]+\b).*\1)[A-Z,]+(?<!,)$
^: the start of the string
(?!,): should not be directly followed by a comma
(?!.*,,): should not be followed by two commas
(?!.*(\b[A-Z]+\b).*\1): should not be followed by a value found twice
[A-Z,]+: should contain letters and commas only
$: the end of the string
(?<!,): should not be directly preceded by a comma
See https://regex101.com/r/1kGVSB/1
I have two patterns for javascript:
/^[A-z0-9]{10}$/ - string of exactly length of 10 of alphanumeric symbols.
and
/^\d+$/ - any number of at least length of one.
How to make the expression of OR string of 10 or any number?
var pattern = /^([A-z0-9]{10})|(\d+)$/;
doesn't work by some reason. It passes at lest
pattern.test("123kjhkjhkj33f"); // true
which is not number and not of length of 10 for A-z0-9 string.
Note that your ^([A-z0-9]{10})|(\d+)$ pattern matches 10 chars from the A-z0-9 ranges at the start of the string (the ^ only modifies the ([A-z0-9]{10}) part (the first alternative branch), or (|) 1 or more digits at the end of the stirng with (\d+)$ (the $ only modifies the (\d+) branch pattern.
Also note that the A-z is a typo, [A-z] does not only match ASCII letters.
You need to fix it as follows:
var pattern = /^(?:[A-Za-z0-9]{10}|\d+)$/;
or with the i modifier:
var pattern = /^(?:[a-z0-9]{10}|\d+)$/i;
See the regex demo.
Note that grouping is important here: the (?:...|...) makes the anchors apply to each of them appropriately.
Details
^ - start of string
(?: - a non-capturing alternation group:
[A-Za-z0-9]{10} - 10 alphanumeric chars
| - or
\d+ - 1 or more digits
) - end of the grouping construct
$ - end of string
I'm using this regex to match some strings:
^([^\s](-)?(\d+)?(\.)?(\d+)?)$/
I'm confusing about why it's permitted to enter two dots, like ..
What I understand is that only allowed to put 1 dash or none (-)?
Any digits with no limit or none (\d+)?
One dot or none (\.)?
Why is allowed to put .. or even .4.6?
Testing done in http://www.regextester.com/
[^\s] means anything that is not a whitespace. This includes dots. Trying to match .. will get you:
[^\s] matches .
(-)? doesn't match
(\d+)? doesn't match
(\.)? matches .
(\d+)? doesn't match
I'll assume you wanted to match numbers (possibly negative/floating):
^-?\d+(\.\d+)?$
^([^\s](-)?(\d+)?(\.)?(\d+)?)$/
Assert position at the beginning of the string ^
Match the regex below and capture its match into backreference number 1 ([^\s](-)?(\d+)?(\.)?(\d+)?)
Match any single character that is NOT present in the list below and that is NOT a line break character (line feed) [^\s]
A single character from the list “\s” (case sensitive) \s
Match the regex below and capture its match into backreference number 2 (-)?
Between zero and one times, as few or as many times as needed to find the longest match in combination with the other quantifiers or alternatives ?
Match the character “-” literally -
Match the regex below and capture its match into backreference number 3 (\d+)?
Between zero and one times, as few or as many times as needed to find the longest match in combination with the other quantifiers or alternatives ?
MySQL does not support any shorthand character classes \d+
Between one and unlimited times, as few or as many times as needed to find the longest match in combination with the other quantifiers or alternatives +
Match the regex below and capture its match into backreference number 4 (\.)?
Between zero and one times, as few or as many times as needed to find the longest match in combination with the other quantifiers or alternatives ?
Match the character “.” literally \.
Match the regex below and capture its match into backreference number 5 (\d+)?
Between zero and one times, as few or as many times as needed to find the longest match in combination with the other quantifiers or alternatives ?
MySQL does not support any shorthand character classes \d+
Between one and unlimited times, as few or as many times as needed to find the longest match in combination with the other quantifiers or alternatives +
Assert position at the very end of the string $
Match the character “/” literally /
Created with RegexBuddy
As I mentioned in my comment, [^\n] is a negated character class that matches .. and as there is another (\.)? pattern, the regex can match 2 consecutive dots (since all of the parts except for [^\s] are optional).
In order not to match strings like .4.5 or .. you just need to add the . to the [^\n] negated character class:
^([^\s.](-)?(\d+)?(\.)?(\d+)?)$
^
See demo. This will not let any . in the initial capturing group.
You can use a lookahead to only disallow the first character as a dot:
^(?!\.)([^\s](-)?(\d+)?(\.)?(\d+)?)$
See another demo
All explanation is available at the online regex testers:
In order to match the numbers in the format you expect, use:
^(?:[-]?\d+\.?\d*|-)$
Human-readable explanation:
^ - start of string and then there are 2 alternatives...
[-]? - optional hyphen
\d+ - 1 or more digits
\.? - optional dot
\d* - 0 or more digits
| -OR-
- - a hyphen
$ - end of string
See demo
I'm trying to exclude some internal IP addresses and some internal IP address formats from viewing certain logos and links in the site.I have multiple range of IP addresses(sample given below). Is it possible to write a regex that could match all the IP addresses in the list below using javascript?
10.X.X.X
12.122.X.X
12.211.X.X
64.X.X.X
64.23.X.X
74.23.211.92
and 10 more
Quote the periods, replace the X's with \d+, and join them all together with pipes:
const allowedIPpatterns = [
"10.X.X.X",
"12.122.X.X",
"12.211.X.X",
"64.X.X.X",
"64.23.X.X",
"74.23.211.92" //, etc.
];
const allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
')$';
const allowedRegexp = new RegExp(allowedRegexStr);
Then you're all set:
'10.1.2.3'.match(allowedRegexp) // => ['10.1.2.3']
'100.1.2.3'.match(allowedRegexp) // => null
How it works:
First, we have to turn the individual IP patterns into regular expressions matching their intent. One regular expression for "all IPs of the form '12.122.X.X'" is this:
^12\.122\.\d+\.\d+$
^ means the match has to start at the beginning of the string; otherwise, 112.122.X.X IPs would also match.
12 etc: digits match themselves
\.: a period in a regex matches any character at all; we want literal periods, so we put a backslash in front.
\d: shorthand for [0-9]; matches any digit.
+: means "1 or more" - 1 or more digits, in this case.
$: similarly to ^, this means the match has to end at the end of the string.
So, we turn the IP patterns into regexes like that. For an individual pattern you could use code like this:
const regexStr = `^` + ipXpattern.
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
`$`;
Which just replaces all .s with \. and Xs with \d+ and sticks the ^ and $ on the ends.
(Note the doubled backslashes; both string parsing and regex parsing use backslashes, so wherever we want a literal one to make it past the string parser to the regular expression parser, we have to double it.)
In a regular expression, the alternation this|that matches anything that matches either this or that. So we can check for a match against all the IP's at once if we to turn the list into a single regex of the form re1|re2|re3|...|relast.
Then we can do some refactoring to make the regex matcher's job easier; in this case, since all the regexes are going to have ^...$, we can move those constraints out of the individual regexes and put them on the whole thing: ^(10\.\d+\.\d+\.\d+|12\.122\.\d+\.\d+|...)$. The parentheses keep the ^ from being only part of the first pattern and $ from being only part of the last. But since plain parentheses capture as well as group, and we don't need to capture anything, I replaced them with the non-grouping version (?:..).
And in this case we can do the global search-and-replace once on the giant string instead of individually on each pattern. So the result is the code above:
const allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '\\d+') +
')$';
That's still just a string; we have to turn it into an actual RegExp object to do the matching:
const allowedRegexp = new RegExp(allowedRegexStr);
As written, this doesn't filter out illegal IPs - for instance, 10.1234.5678.9012 would match the first pattern. If you want to limit the individual byte values to the decimal range 0-255, you can use a more complicated regex than \d+, like this:
(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])
That matches "any one or two digits, or '1' followed by any two digits, or '2' followed by any of '0' through '4' followed by any digit, or '25' followed by any of '0' through '5'". Replacing the \d with that turns the full string-munging expression into this:
const allowedRegexStr = '^(?:' +
allowedIPpatterns.
join('|').
replace(/\./g, '\\.').
replace(/X/g, '(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])') +
')$';
And makes the actual regex look much more unwieldy:
^(?:10\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5]).(?:\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])|12\.122\....
but you don't have to look at it, just match against it. :)
You could do it in regex, but it's not going to be pretty, especially since JavaScript doesn't even support verbose regexes, which means that it has to be one humongous line of regex without any comments. Furthermore, regexes are ill-suited for matching ranges of numbers. I suspect that there are better tools for dealing with this.
Well, OK, here goes (for the samples you provided):
var myregexp = /\b(?:74\.23\.211\.92|(?:12\.(?:122|211)|64\.23)\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])|(?:10|64)\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))\b/g;
As a verbose ("readable") regex:
\b # start of number
(?: # Either match...
74\.23\.211\.92 # an explicit address
| # or
(?: # an address that starts with
12\.(?:122|211) # 12.122 or 12.211
| # or
64\.23 # 64.23
)
\. # .
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]) # followed by 0..255
| # or
(?:10|64) # match 10 or 64
\. # .
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]) # followed by 0..255
)
\b # end of number
/^(X|\d{1,3})(\.(X|\d{1,3})){3}$/ should do it.
If you don't actually need to match the "X" character you could use this:
\b(?:\d{1,3}\.){3}\d{1,3}\b
Otherwise I would use the solution cebarrett provided.
I'm not entirely sure of what you're trying to achieve here (doesn't look anyone else is either).
However, if it's validation, then here's a solution to validate an IP address that doesn't use RegEx. First, split the input string at the dot. Then using parseInt on the number, make sure it isn't higher than 255.
function ipValidator(ipAddress) {
var ipSegments = ipAddress.split('.');
for(var i=0;i<ipSegments.length;i++)
{
if(parseInt(ipSegments[i]) > 255){
return 'fail';
}
}
return 'match';
}
Running the following returns 'match':
document.write(ipValidator('10.255.255.125'));
Whereas this will return 'fail':
document.write(ipValidator('10.255.256.125'));
Here's a noted version in a jsfiddle with some examples, http://jsfiddle.net/VGp2p/2/
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's a C# regular expression that'll validate currency, float or integer?
How can I validate currency amount using regular expressions in JavaScript?
Decimals separator: ,
Tens, hundreds, etc. separator: .
Pattern: ###.###.###,##
Examples of valid amounts:
1
1234
123456
1.234
123.456
1.234.567
1,23
12345,67
1234567,89
1.234,56
123.456,78
1.234.567,89
EDIT
I forgot to mention that the following pattern is also valid: ###,###,###.##
Based solely on the criteria you gave, this is what I came up with.
/(?:^\d{1,3}(?:\.?\d{3})*(?:,\d{2})?$)|(?:^\d{1,3}(?:,?\d{3})*(?:\.\d{2})?$)/
http://refiddle.com/18u
It is ugly, and it will only get worse as you find more cases that need to be matched. You'd be well served to find and use some validation library rather than try to do this all yourself, especially not in a single regular expression.
Updated to reflect added requirements.
Updated again in regard to comment below.
It would match 123.123,123 (three trailing digits instead of two) because it would accept either comma or period as both the thousands and decimal separators. To fix that, I've now essentially doubled up the expression; either it matches the whole thing with commas for separators and a period as the radix point, or it matches the whole thing with periods for separators and a comma as the radix point.
See what I mean about it getting messier? (^_^)
Here's the verbose explanation:
(?:^ # beginning of string
\d{1,3} # one, two, or three digits
(?:
\.? # optional separating period
\d{3} # followed by exactly three digits
)* # repeat this subpattern (.###) any number of times (including none at all)
(?:,\d{2})? # optionally followed by a decimal comma and exactly two digits
$) # End of string.
| # ...or...
(?:^ # beginning of string
\d{1,3} # one, two, or three digits
(?:
,? # optional separating comma
\d{3} # followed by exactly three digits
)* # repeat this subpattern (,###) any number of times (including none at all)
(?:\.\d{2})? # optionally followed by a decimal perioda and exactly two digits
$) # End of string.
One thing that makes it look more complicated is all the ?: in there. Normally a regular expression captures (returns matches for) all of the subpatterns too. All ?: does is say to not bother to capture the subpattern. So technically, the full thing would still match your entire string if you took all of the ?: out, which looks a bit clearer:
/(^\d{1,3}(\.?\d{3})*(,\d{2})?$)|(^\d{1,3}(,?\d{3})*(\.\d{2})?$)/
Also, regular-expressions.info is a great resource.
This works for all your examples:
/^(?:\d+(?:,\d{3})*(?:\.\d{2})?|\d+(?:\.\d{3})*(?:,\d{2})?)$/
As a verbose regex (not supported in JavaScript, though):
^ # Start of string
(?: # Match either...
\d+ # one or more digits
(?:,\d{3})* # optionally followed by comma-separated threes of digits
(?:\.\d{2})? # optionally followed by a decimal point and exactly two digits
| # ...or...
\d+ # one or more digits
(?:\.\d{3})* # optionally followed by point-separated threes of digits
(?:,\d{2})? # optionally followed by a decimal comma and exactly two digits
) # End of alternation
$ # End of string.
This handles everything above except for the (just added?) 123.45 case:
function foo (s) { return s.match(/^\d{1,3}(?:\.?\d{3})*(?:,\d\d)?$/) }
Do you need to handle multiple separator formats?