regex for matching latitude, longitudes without any character - regex

I am looking for one regex which strictly allows 2 floating point numbers which are comma separated.
Test cases:
0,0
0.021312311323,0
0,0.012312312312
1.1,0.9836373
Regex that I have tried is
^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$\D+|\d*\.?\d+
These are latitudes and longitudes but I just want 2 values in these paremeters.
This regex fails in:
-10a, 10a
10a,10b
I would really appreciate any help and guidance.

Your regex ends with a couple of redundant patterns, you should remove \D+|\d*\.?\d+ after $. As $ means the end of string, there can be no more text after it, and the \D+|\d*\.?\d+ requires one or more non-digit chars, or just matches any float or integer number with \d*\.?\d+ - this matched your unwelcome strings.
You can use
^([-+]?(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?)),\s*([-+]?(?:180(?:\.0+)?|(?:1[0-7]\d|[1-9]?\d)(?:\.\d+)?))$
See the regex demo. Note I converted some capturing groups into non-capturing, so that there remain just two "notional" capturing groups in the pattern.
Details
^ - start of string
([-+]?(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?)) - Group 1:
[-+]? - an optional - or +
(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?) - either a number from 0 to 89 ([1-8]?\d) and then an optional fractional part ((?:\.\d+)?) or 90 and then an optional . followed with one or more 0 chars
,\s* - a comma and 0+ whitespace chars
([-+]?(?:180(?:\.0+)?|(?:1[0-7]\d|[1-9]?\d)(?:\.\d+)?)) - Group 2:
[-+]? - an optional - or +
(?:180(?:\.0+)?|(?:1[0-7]\d|[1-9]?\d)(?:\.\d+)?) - either a 180 number followed with an optional . + one or more 0 chars, or a number from 0 to 179 and then an optional fractional part
$ - end of string.

Your regular expression is almost correct. You should have stopped at $ indicating the end of the string.
const testCases = [ "0,0",
"0.021312311323,0",
"0,0.012312312312",
"1.1,0.9836373",
"-10a, 10a",
"10a,10b"];
const re = /^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/g;
testCases.forEach(tc => {
if(tc.match(re)) {
console.log(" VALID : " + tc );
} else {
console.log("NOT VALID : " + tc);
}
});

Related

Regex - Validation of numeric with up to 10 decimal places (0.01 - 100.0000000000)

I am just curious if this regex expression will be able to be shorten. it should allow ten digits.
/^(?!0+(?:\.0+)?$)(\d{1,2}\.\d{1,10}|\d{1,2}|(100)|(100\\.00)|(100\\.0000000000)|(100\\.000000000)|(100\\.00000000)|(100\\.0000000)|(100\\.000000)|(100\\.00000)|(100\\.0000)|(100\\.0000)|(100\\.000)|(100\\.0))$/
You need to use
/^(?![0.]+$)(?:\d{1,2}(?:\.\d{1,10})?|100(?:\.0{1,10})?)$/
See the regex demo.
Details:
^ - start of string
(?![0.]+$) - no only 0 and/or . chars till end of string are allowed
(?: - either of
\d{1,2}(?:\.\d{1,10})? - one or two digits and then an optional occurrence of a . and one to ten digits
| - or
100(?:\.0{1,10})? - 100 and then an optional occurrence of a . and one to ten 0 chars
) - end of the group
$ - end of string.

Match any number BUT positive 1-10

I've tried the following without any success
^((\d{1,})\b[^1-10]\b)$
What should match:
"11", "0", "-1", "100" and any number which is not 1-9
What shouldn't match:
"10", "1", "abc11", "11abc", "a11b" and any number >= 1 AND <= 10
It seems you want
^(?!(?:[1-9]|10)$)-?\d+$
See the regex demo. Details:
^ - start of string
(?!(?:[1-9]|10)$) - a negative lookahead that fails the match if there is a digit from 1 to 9 or 10 substring followed with end of string position immediately to the right of the current location
-? - an optional -
\d+ - one or more digits
$ - end of string.
If you cannot use lookarounds, you can use
^(-[0-9]+|0|1[1-9]|[2-9][0-9]|[0-9]{3,})$
See this regex demo. This regex matches:
^ - start of string
( - start of a capturing group:
-[0-9]+| - - and then one or more digits, or
0| - 0, or
1[1-9]| - 1 and then a non-zero digit, or
[2-9][0-9]| - a digit from 2 to 9 and then any one digit, or
[0-9]{3,} - any three or more digits
) - end of the group
$ - end of string
This solution is not very elegant, but should match the data and rules you posted:
^((-1|0)|(\d{2,}))$
Mini description of the parts of the expression:
^ Start of string
(-1|0) the two "edge case" (Yes, hardcoded)
(\d{2,}) atleast two digits
$ end of string
(,) just grouping, to

How to make an If Then Else Regex conditional statement

I am trying to make an If-Then-Else conditional statement in regular expressions.
The regex takes as input a string representing a filename.
Here are my test strings...
The Edge Of Seventeen 2016 720p.mp4
20180511 2314 - Film4 - Northern Soul.ts
20150526 2059 - BBC Four - We Need to Talk About Kevin.ts
In the first string, 2016 represents a year but in the other two strings 2314 and 2059 represent times in 24 hour clock format.
The filename should be retained unchanged if it matches this regex:
\d{8} \d{4} -.*?- .*?\.ts
Which I have tested and it works. It can match these test strings:
20180511 2314 - Film4 - Northern Soul.ts
20150526 2059 - BBC Four - We Need to Talk About Kevin.ts
If the filename does not match that first regex then this regex should be applied to it:
(.*[^ _\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9][0-9]|20[0-9][0-9])([ _\,\.\(\)\[\]\-]|[^0-9]$)?
This is a cleandatetime regexp that is used by Kodi to remove everything from a string AFTER a four digit number, if it exists, representing a date between 1900 and 2099. I have also tested this and it works.
Here is what I have tried to make the If-Then-Else Regex but it doesn't work:
I use this format --> (?(A)X|Y)
(?(\d{8} \d{4} -.*?- .*?\.ts)^.*$|(.*[^ _\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9][0-9]|20[0-9][0-9])([ _\,\.\(\)\[\]\-]|[^0-9]$)?)
This is A
\d{8} \d{4} -.*?- .*?\.ts
This is X
^.*$
This is Y
(.*[^ _\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9][0-9]|20[0-9][0-9])([ _\,\.\(\)\[\]\-]|[^0-9]$)?
This is the expected output...
Test string:
The Edge Of Seventeen 2016 720p.mp4
Expected output:
"The Edge Of Seventeen 2016 " (quotes only included to show that a trailing space can be left at the end)
Test String:
20180511 2314 - Film4 - Northern Soul.ts
Expected output:
20180511 2314 - Film4 - Northern Soul.ts
Test String:
20150526 2059 - BBC Four - We Need to Talk About Kevin.ts
Expected output:
20150526 2059 - BBC Four - We Need to Talk About Kevin.ts
I am looking for a solution entirely in regular expression syntax. Can someone help me to make it work please?
Cheers,
Flex
You may use a PCRE pattern like
^(?!\d{8} \d{4} -.*?- .*?\.ts$)(.*[^ _,.()\[\]-][ _.()\[\]-]+(?:19|20)[0-9]{2})(?:[ _,.()\[\]-]|[^0-9]$)?.*
Replace with $1, see the regex demo.
It matches
^ - start of string
(?!\d{8} \d{4} -.*?- .*?\.ts$) - the negative lookahead fails the match if the whole string matches
\d{8} \d{4} - 8 digits, space, 4 digits, space
-.*?- .*? - -, then any 0 or more chars other than line break chars, as few as possible, - and a space and then again 0 or more chars other than line break chars, as few as possible
\.ts$ - .ts at the end of string
(.*[^ _,.()\[\]-][ _.()\[\]-]+(?:19|20)[0-9]{2})(?:[ _,.()\[\]-]|[^0-9]$)?.*: an optional Group 1 and then the rest of the string:
.* - any 0+ chars other than line break chars as many as possible
[^ _,.()\[\]-] - a char other than
[ _.()\[\]-]+ - 1+ spaces, _, ., (, ), [, ] or -
(?:19|20) - 19 or 20
[0-9]{2} - two digits
(?:[ _,.()\[\]-]|[^0-9]$)? - an optional non-capturing group matching a space, _, ., (, ), [, ] or - or any char other than digit at the end of the string.
.*[^ _,.()\[\]-][ _.()\[\]-]+(?:19|20)[0-9]{2})(?:[ _,.()\[\]-]|[^0-9]$
.* - any 0+ chars other than line break chars as many as possible.
Since you have mentioned that A, X and Y are tested and found working, and since there are only 2 patterns, I think this pattern will work (Python style):
pattern = "(.?(?=" + A + ")" + X + ")|(" + Y + ")"
which means:
(.?(?=A)X)|(Y)
Explanation:
There are two groups - one for X and one for Y.
The group for capturing X starts with .? just to make the engine start moving and check if there is a part matching X ahead (a lookahead). If yes, it continues with matching X since it will encounter it after the lookahead block.
If in (2), the lookahead doesn't match, then the | (or) part, which is Y will take over. If that matches, you get a result. Else, no output.
(Sadly, the patterns for A and Y you posted were not working for me on Python, so I replaced them with my own for testing. Please do confirm if the pattern is working with the original ones.)

Regex for parse name with one or more words after double number and before 2 or more spaces

Problem:
How create regex to parse "DISNAY LAND 2.0 GCP" like name from Array of lines in Scala like this:
DE1ALAT0002 32.4756 -86.4393 106.1 ZQ DISNAY LAND 2.0 GCP 23456
//For using in code:
val regex = """(?:[\d\.\d]){2}\s*(?:[\d.\d])\s*(ZQ)\s*([A-Z])""".r . // my attempt
val getName = row match {
case regex(name) => name
case _ =>
}
I'm sure only in:
1) there is different number of spaces between values
2) useful value "DISNAY LAND 2.0 GCP" come after double number and "ZQ" letters
3) name separating with one space and may consist of one or many words
4) name ending with two or more spaces
sorry if I repeat the question, but after a long search I did not find the right solution
Many thank for answers
You may use an .unanchored pattern like
\d\.\d+\s+ZQ\s+(\S+(?:\s\S+)*)
See the regex demo. Details
\d\.\d+ - 1 digit, . and then 1+ digits
\s+ - 1+ whitespaces
ZQ - ZQ substring
\s+ - 1+ whitespaces (here, the left-hand side context definition ends, now, starting to capture the value we need to return)
(\S+(?:\s\S+)*) - Capturing group 1:
\S+ - 1 or more non-whitespace chars
(?:\s\S+)* - a non-capturing group that matches 0 or more sequences of a single whitespace (\s) and then 1+ non-whitespace chars (so, up to the double whitespace or end of string).
Scala demo:
val regex = """\d\.\d+\s+ZQ\s+(\S+(?:\s\S+)*)""".r.unanchored
val row = "DE1ALAT0002 32.4756 -86.4393 106.1 ZQ DISNAY LAND 2.0 GCP 23456"
val getName = row match {
case regex(name) => name
case _ =>
}
print(getName)
Output: DISNAY LAND 2.0 GCP

Regex range between 0 and 100 including two decimal

I'm trying to figure out a regex expression that does the following. Both conditions below must be true:
1) Between 0 and 100 inclusive
2) Can contain one or two decimals only but not obligatory.
It should not allow 100.01 or 100.1
100 is the maximum value, or 100.0 or 100.00
I tried ^(100(?:\.00)?|0(?:\.\d\d)?|\d?\d(?:\.\d\d)?)$
which helped me in this question
but this does not accept 99.0 (one decimal).
I'm probably very close.
You just need to make each second decimal digit optional:
^(?:100(?:\.00?)?|\d?\d(?:\.\d\d?)?)$
^ ^
See the updated regex demo. The 0(?:\.\d\d)? alternative is covered by \d?\d(?:\.\d\d)? one (as per Sebastian's comment) and can thus be removed.
The ? quantifier matches one or zero occurrences of the subpattern it quantifies.
Pattern details:
^ - start of string
(?: - start of an alternation group:
100(?:\.00?)? - 100, 100.0 or 100.00 (the .00 is optional and the last 0 is optional, too)
\d?\d(?:\.\d\d?)? - an optional digit followed by an obligatory digit followed with an optional sequence of a dot, a digit and an optional digit.
) - end of the alternation group
$ - end of string.
BONUS: If the number can have either . (dot) or , (comma) as a decimal separator, you can replace all \. patterns in the regex with [.,]:
^(?:100(?:[.,]00?)?|\d?\d(?:[.,]\d\d?)?)$