0

I found this Regular Expression which only matches for valid coordinates.

^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$

(Which I found from here)

How do I negate it so it matches anything that isn't a valid coordinate? I've tried using ?! but not matter where I put it, it doesn't seem to work

Edit: Edited the Regular Expression because I didn't copy it correctly

3 Answers3

1

If you want to negate a whole regex like this you'd better not try to phrase this inside the regular expression. The programming language you use (in your case javascript) will have a function to match against a string. (i gues in your case its string.matches(regex) just negate that expression !string.matches(regex).

If you want to have the whole text without the coordinates then you could do string.replaceAll(regex, "") and you get the text without the matching components.

Chris
  • 7,675
  • 8
  • 51
  • 101
  • 1
    In JavaScript it's `regex.test(string)`. There's also `regex.exec(string)` which is *basically* like `string.match(regex)`. Very confusing I know. – kelsny Aug 28 '22 at 16:52
0

The negation by wrapping all in a ^(?! ) construct will work, but your regex is not correct -- you lost some essential characters, so that it has ,* making the comma optional so that many single numbers will also be matched. The original (correct) regex has ,\s* at that position in the regex. If you don't want to allow such white space, then remove \s*, not just \s...

So the opposite test can be done with:

^(?![-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$)

If you actually want to capture the line that this regex matches, append .* to this regex.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • I've tried that, and it works for the most part. However when I try to replace the non-matched patterns, it doesn't work. https://jsfiddle.net/tLe06rfb/ –  Aug 28 '22 at 17:05
  • Like I wrote in the answer, when you need to *capture* the line that is wrong, then you need to append `.*` to the regex. This is what you need for your `replace` code to work: https://jsfiddle.net/4rczkx20/ – trincot Aug 28 '22 at 17:07
  • It's returning me an empty string :\ –  Aug 28 '22 at 17:18
  • Yes, that is what `replace` does when you provide as replacement string an empty string... Why is that not what you expected? – trincot Aug 28 '22 at 17:18
  • I was hoping it would replace the link and return me the coordinates, as I'm extracting the coordinates out –  Aug 28 '22 at 17:20
  • But wait! You are working on input that has more text, not just coordinates. But do realise that `^` in your original regex means "start of the input string". That regex is intended to verify that the **whole** input matches or not. So this is a different use case. If you want to verify *part* of a string, you need a different regex, but then your question is off. – trincot Aug 28 '22 at 17:21
  • What RegEx would I need to use to get the whole string then? –  Aug 28 '22 at 17:23
  • I'm lost as to what you want. Is your question really "how can I remove text that is surrounding valid coordinates?" Why then not just *match* the coordinates with the original regex, and forget about the rest? – trincot Aug 28 '22 at 17:24
0

If you simply want to extract a valid coordinate from a longer string you don't need to negate the regex. You can use this regex replace:

let coord = str.replace(/^.*?([-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)).*$/, '$1');

Explanation:

  • ^.*? - is a non-greedy scan that will scan up to the first pattern found that follows; if you use ^.* instead, you'll scan up to the last pattern (in case there is more than one); pick the one you want
  • ( ... ) - defines a capture group, anything within the parenthesis is captured and can be referenced as $1 in the replacement; add your regex sans anchors
  • .*$ - eat up anything that is left
  • if you expect newlines in your input string use [\s\S] instead of ., e.g. start with ^[\s\S]*? and end with [\s\S]*$
Peter Thoeny
  • 7,379
  • 1
  • 10
  • 20