Regex for two numbers and space between - regex

I need to validate a property which can contain a two numbers(can be both float and integer) and they are separated with a space
So this should be valid: 72 72,278
This should be also valid: 72 72
this shouldn't be valid: 45 45 - more than one space between
this shouldn't be valid : 2,2 - just one float number
this shouldn't be valid: 23 # 12 - if it contain any other characters
I've tried like this:
\d+[ ,]\d+
but this does not validate correctly if I have two float numbers, only if I have two integers and the space
I've also tried this
[0-9 .,]+
This validates what I need, but also validates invalid items

You can try something like so: ^\d+(,\d+)?(\s\d+(,\d+)?)+$, example here.
This assumes that:
The , is your floating point delimeter;
Negative numbers aren't allowed.
EDIT
As per Wiktor's comment, this solution accepts two or more numbers separated by a white space. To only accept 2 numbers, the following needs to be used: ^\d+(,\d+)?(\s\d+(,\d+)?)$. (Notice the + at the end has been removed, changing the logic to 1 or more to just 1).
EDIT 2
As per your comment, if you need to match both the , and the . as separator, you would need to use something such as this: ^\d+([,.]\d+)?(\s\d+([,.]\d+)?)+$. This will accept both characters as decimal separators, however, please note that as is, can accept something of the sort: 12.34 34,56.

Related

regular expression that accepts numbers like 1,000.10? [duplicate]

I need regex to validate a number that could contain thousand separators or decimals using javascript.
Max value being 9,999,999.99
Min value 0.01
Other valid values:
11,111
11.1
1,111.11
INVALID values:
1111
1111,11
,111
111,
I've searched all over with no joy.
/^\d{1,3}(,\d{3})*(\.\d+)?$/
About the minimum and maximum values... Well, I wouldn't do it with a regex, but you can add lookaheads at the beginning:
/^(?!0+\.00)(?=.{1,9}(\.|$))\d{1,3}(,\d{3})*(\.\d+)?$/
Note: this allows 0,999.00, so you may want to change it to:
/^(?!0+\.00)(?=.{1,9}(\.|$))(?!0(?!\.))\d{1,3}(,\d{3})*(\.\d+)?$/
which would not allow a leading 0.
Edit:
Tests: http://jsfiddle.net/pKsYq/2/
((\d){1,3})+([,][\d]{3})*([.](\d)*)?
It worked on a few, but I'm still learning regex as well.
The logic should be 1-3 digits 0-1 times, 1 comma followed by 3 digits any number of times, and a single . followed by any number of digits 0-1 times
First, I want to point out that if you own the form the data is coming from, the best way to restrict the input is to use the proper form elements (aka, number field)
<input type="number" name="size" min="0.01" max="9,999,999.99" step="0.01">
Whether "," can be entered will be based on the browser, but the browser will always give you the value as an actual number. (Remember that all form data must be validated/sanitized server side as well. Never trust the client)
Second, I'd like to expand on the other answers to a more robust (platform independent)/modifiable regex.
You should surround the regex with ^ and $ to make sure you are matching against the whole number, not just a subset of it. ex ^<my_regex>$
The right side of the decimal is optional, so we can put it in an optional group (<regex>)?
Matching a literal period and than any chain of numbers is simply \.\d+
If you want to insist the last number after the decimal isn't a 0, you can use [1-9] for "a non-zero number" so \.\d+[1-9]
For the left side of the decimal, the leading number will be non-zero, or the number is zero. So ([1-9]<rest-of-number-regex>|0)
The first group of numbers will be 1-3 digits so [1-9]\d{0,2}
After that, we have to add digits in 3s so (,\d{3})*
Remember ? means optional, so to make the , optional is just (,?\d{3})*
Putting it all together
^([1-9]\d{0,2}(,?\d{3})*|0)(\.\d+[1-9])?$
Tezra's formula fails for '1.' or '1.0'. For my purposes, I allow leading and trailing zeros, as well as a leading + or - sign, like so:
^[-+]?((\d{1,3}(,\d{3})*)|(\d*))(\.|\.\d*)?$
In a recent project we needed to alter this version in order to meet international requirements.
This is what we used: ^-?(\d{1,3}(?<tt>\.|\,| ))((\d{3}\k<tt>)*(\d{3}(?!\k<tt>)[\.|\,]))?\d*$
Creating a named group (?<tt>\.|\,| ) allowed us to use the negative look ahead (?!\k<tt>)[\.|\,]) later to ensure the thousands separator and the decimal point are in fact different.
I have used below regrex for following retrictions -
^(?!0|\.00)[0-9]+(,\d{3})*(.[0-9]{0,2})$
Not allow 0 and .00.
','(thousand seperator) after 3 digits.
'.' (decimal upto 2 decimal places).

Optimization of Regular Expression to match numbers bigger or equal to 50

I want to check if a number is 50 or more using a regular expression. This in itself is no problem but the number field has another regex checking the format of the entered number.
The number will be in the continental format: 123.456,78 (a dot between groups of three digits and always a comma with 2 digits at the end)
Examples:
100.000,00
50.000,00
50,00
34,34
etc.
I want to capture numbers which are 50 or more. So from the four examples above the first three should be matched.
I've come up with this rather complicated one and am wondering if there is an easier way to do this.
^(\d{1,3}[.]|[5-9][0-9]|\d{3}|[.]\d{1,3})*[,]\d{2}$
EDIT
I want to match continental numbers here. The numbers have this format due to internal regulations and specify a price.
Example: 1000 EUR would be written as 1.000,00 EUR
50000 as 50.000,00 and so on.
It's a matter of taste, obviously, but using a negative lookahead gives a simple solution.
^(?!([1-4]?\d),)[1-9](\d{1,2})?(\.\d{3})*,\d{2}\b
In words: starting from a boundary ignore all numbers that start with 1 digit OR 2 digits (the first being a 1,2,3 or 4), followed by a comma.
Check on regex101.com
Try:
EDIT ^(.{3,}|[5-9]\d),\d{2}$
It checks if:
there 3 chars or more before the ,
there are 2 numbers before the , and the first is between 5 and 9
and then a , and 2 numbers
Donno if it answer your question as it'll return true for:
aa50,00
1sdf,54
But this assumes that your original string is a number in the format you expect (as it was not a requirement in your question).
EDIT 3
The regex below tests if the number is valid referring to the continental format and if it's equal or greater than 50. See tests here.
Regex: ^((([1-9]\d{0,2}\.)(\d{3}\.){0,}\d{3})|([1-9]\d{2})|([5-9]\d)),\d{2}$
Explanation (d is a number):
([1-9]\d{0,2}\.): either d., dd. or ddd. one time with the first d between 1 and 9.
(\d{3}\.){0,}: ddd. zero or x time
\d{3}: ddd 3 digit
These 3 parts combined match any numbers equals or greater than 1000 like: 1.000, 22.002 or 100.000.000.
([1-9]\d{2}): any number between 100 and 999.
([5-9]\d)): a number between 5 and 9 followed by a number. Matches anything between 50 and 99.
So it's either the one of the parts above or this one.
Then ,\d{2}$ matches the comma and the two last digits.
I have named all inner groups, for better understanding what part of number is matched by each group. After you understand how it works, change all ?P<..> to ?:.
This one is for any dec number in the continental format.
^(?P<common_int>(?P<int>(?P<int_start>[1-9]\d{1,2}|[1-9]\d|[1-9])(?P<int_end>\.\d{3})*|0)(?!,)|(?P<dec_int_having_frac>(?P<dec_int>(?P<dec_int_start>[1-9]\d{1,2}|[1-9]\d|[1-9])(?P<dec_int_end>\.\d{3})*,)|0,|,)(?=\d))(?P<frac_from_comma>(?<=,)(?P<frac>(?P<frac_start>\d{3}\.)*(?P<frac_end>\d{1,3})))?$
test
This one is for the same with the limit number>=50
^(?P<common_int>(?P<int>(?P<int_start>[1-9]\d{1,2}|[1-9]\d|[1-9])(?P<int_end>\.\d{3})+|(?P<int_short>[1-9]\d{2}|[5-9]\d))(?!,)|(?P<dec_int_having_frac>(?P<dec_int>(?P<dec_int_start>[1-9]\d{1,2}|[1-9]\d|[1-9])(?P<dec_int_end>\.\d{3})+,)|(?P<dec_short_int>[1-9]\d{2}|[5-9]\d),)(?=\d))(?P<frac_from_comma>(?<=,)(?P<frac>(?P<frac_start>\d{3}\.)*(?P<frac_end>\d{1,3})))?$
tests
If you always have the integer part under 999.999 and fractal part always 2 digits, it will be a bit more simple:
^(?P<dec_int_having_frac>(?P<dec_int>(?P<dec_int_start>[1-9]\d{1,2}|[1-9]\d|[1-9])(?P<dec_int_end>\.\d{3})?,)|(?P<dec_short_int>[1-9]\d{2}|[5-9]\d),)(?=\d)(?P<frac_from_comma>(?<=,)(?P<frac>(?P<frac_end>\d{1,2})))?$
test
If you can guarantee that the number is correctly formed -- that is, that the regex isn't expected to detect that 5,0.1 is invalid, then there are a limited number of passing cases:
ends with \d{3}
ends with [5-9]\d
contains \d{3},
contains [5-9]\d,
It's not actually necessary to do anything with \.
The easiest regex is to code for each of these individually:
(\d{3}$|[5-9]\d$|\d{3},|[5-9]\d)
You could make it more compact and efficient by merging some of the cases:
(\d{3}[$,]|[5-9]\d[$,])
If you need to also validate the format, you will need extra complexity. I would advise against attempting to do both in a single regex.
However unless you have a very good reason for having to do this with a regex, I recommend against it. Parse the string into an integer, and compare it with 50.

Extract Number from String Field, Including Decimal (Postgres 9.5)

Suppose I have a field:
product_strength
10MG/ML
0.25MG
25MG
0.125MG
How do I extract just the "numeric" part and then cast to numeric? I can get this far: regexp_replace(product_strength, '(\D|!\.)','','g')::numeric AS result_numeric
But the problem with this is that it doesn't actually account for the decimal. In other words, this returns
product_strength result_numeric
10MG/ML 10
0.25MG 25
25MG 25
0.125MG 125
But I would want to return
product_strength result_numeric
10MG/ML 10
0.25MG 0.25
25MG 25
0.125MG 0.125
I would use regexp_matches for this:
select (regexp_matches(product_strength, '[0-9]+\.?[0-9]*'))[1]::numeric
from the_table
regexp_matches() returns an array of all matched strings, that's why the [1] is needed.
Try this regex to match the numbers;
\d+\.?\d*
Edit: as "Boolean_Type" says, if you need negative numbers too, you could add in an optional negative sign, and use;
\-?\d+\.?\d*

Find repeating gps using regular expression

I work with text files, and I need to be able to see when the gps (last 3 columns of csv) "hangs up" for more than a few lines.
So for example, usually, part of a text file looks like this:
5451,1667,180007,35.7397387,97.8161897,375.8
5448,1053z,180006,35.7397407,97.8161814,375.7
5444,1667,180005,35.7397445,97.8161674,375.6
5439,1668,180004,35.7397483,97.8161526,375.5
5435,1669,180003,35.7397518,97.8161379,375.5
5431,1669,180002,35.7397554,97.8161269,375.6
5426,1054z,180001,35.7397584,97.8161115,375.6
5420,1670,175959,35.7397649,97.8160931,375.9
But sometimes there is an error with the gps and it looks like this:
36859,1598,202603.00,35.8867316,99.2515545,555.700
36859,1598,202608.00,35.8867316,99.2515545,555.700
36859,1142z,202610.00,35.8867316,99.2515545,555.700
36859,1597,202612.00,35.8867316,99.2515545,555.700
36859,1597,202614.00,35.8867316,99.2515545,555.700
36859,1596,202616.00,35.8867316,99.2515545,555.700
36859,1595,202618.00,35.8867316,99.2515545,555.700
I need to be able to figure out a way to search for matching strings of 7 different numbers, (the decimal portion of the gps) but so far I've only been able to figure out how to search for repeating #s or consecutive numbers.
Any ideas?
If you were to find such repetitions in an editor (such as Notepad++), you could use the following regex to find 4 or more repeating lines:
([^,]+(?:,[^,]+){2})\v+(?:(?:[^,]+,){3}\1(?:\v+|$)){3,}
To go a bit into detail
([^,]+(?:,[^,]+){2})\v+ is a group consisting of one or more non-commas followed by comma and another one or more non-commas followed by a vertical space (linebreak), that is not part of the group (e.g. 1,1,1\n)
(?:[^,]+,){3} matches one or more non-commas followed by comma, three times (your columns that don't have to be considered)
\1 is a backreference to group 1, matching if it contains exactly the same as group 1
(?:\v+|$) matches either another vertical whitespaces or the end of the text
{3,} for 3 or more repetitions - increase it if you want more
Here you can see, how it works
However, if you are using any programming language to check this, I wouldn't walk on the path of regex, as checking for those repetitions can be done a lot easier. Here is one example in Python, I hope you can adopt it for your needs:
oldcoords = [0,0,0]
lines = [line.rstrip('\n') for line in open(r'C:\temp\gps.csv')]
for line in lines:
gpscoords = line.split(',')[3:6]
if gpscoords == oldcoords:
repetitions += 1
else:
oldcoords = gpscoords
repetitions = 0
if repetitions == 4: #or however you define more than a few
print(', '.join(gpscoords) + ' is repeated')
If you can use perl, and if I understood you:
perl -ne 'm/^[^,]*,[^,]*,[^,]*,([^,]*,[^,]*,[^,]*$)/g; $current_line=$1; ++$line_number; if ($prev_line==$current_line){$equals++} else {if ($equals>=6){ print "Last three fields in lines ".($line_number-$equals-1)." to ".($line_number-1)." are equals to:\n$prev_line" } ; $equals=0}; $prev_line=$current_line' < onlyreplacethiswithyourfilepath should do the trick.
Sample output:
Last three fields in lines 1 to 7 are equals to:
35.8867316,99.2515545,555.700
Last three fields in lines 16 to 22 are equals to:
37.8782116,99.7825545,572.810
Last three fields in lines 31 to 44 are equals to:
36.6868916,77.2594245,581.358
Last three fields in lines 57 to 63 are equals to:
35.5128764,71.2874545,575.631

Regular expression for secret code

I've created one text field which accepts the product code.
I have tried many ways and got disappointed.
The product code is having some validations like follows,
Product code :315299AZ
1.First 2 digits ranges from[01-31].,should not contain 00.
2.Second 2 digits ranges from [01-52]., should not contain 00.
3.Third 2 digits ranges from [00-99].
4.Last 2 are optional. But should accept only alphabets. Should not accepts numbers.
Please someone help me to get out of it.
You can use the following regex :
(?!00)(([0-2][0-9])|31|30)(?!00)(([0-4][0-9])|51|50|52)(\d{2})([a-zA-Z]{2})?
(?!00) is a negative look-ahead that doesn't allows 00.
Debuggex Demo
There you go:
((0[1-9])|([1-2]\d)|(3[0-1]))((0[1-9])|([1-4]\d)|(5[0-2]))\d{2}([a-zA-Z]{2})?
If you don't like look-aheads.
I know it's not the spirit, but any sensible language supporting regular expressions should allow you to access groups, hence do something along these lines (pseudocode follows):
if product_code matches /^(\d\d)(\d\d)\d\d([a-zA-Z]{2})?$/ {
assert 1 <= int($1) <= 31 // validate first group
assert 1 <= int($2) <= 52 // validate second group
}
Bonus: you can actually read it.
(This is assuming the last optional group contains either two or zero characters. If one character is acceptable, you can replace it with [a-zA-Z]{0,2})