Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A more concise version of this Regular Expression?

Tags:

java

regex

I am trying to match an integer or decimal number, followed by two dots .., followed by another integer or decimal number. On each side of the dots, the numbers are optional, but they must be present on one side or the other. I will be using Java for the actual implementation (String#matches()).

For example, these should match:

  • ..12
  • 12..
  • 12..24
  • 12.23..14.25

While these should not:

  • ..
  • foo
  • foo..bar
  • bazz12..12buzz
  • foo11..22
  • 11..22efg

This is the best I have been able to come up with:

(^(\d+\.?\d+)\.\.(\d+\.?\d+)?$)|(^(\d+\.?\d+)?\.\.(\d+\.?\d+)$)

I feel like it could be better. Am I wrong? Note that I have two clauses that are virtually the same with the pipe in the middle, the only difference is one matches ..12 and the other matches 12..

Edit: Thanks for all the input! I picked @anubhava because I asked for the shortest. Also thanks for pointing out the errors in my original expresion!

like image 737
eric Avatar asked Dec 19 '22 19:12

eric


1 Answers

You can use a lookahead to shorten the regex:

^(?=\.*\d)(?:\d+(?:\.\d+)?)?\.\.(?:\d+(?:\.\d+)?)?$

Java regex:

Pattern p = 
        Pattern.compile("^(?=\\.*\\d)(?:\\d+(?:\\.\\d+)?)?\\.\\.(?:\\d+(?:\\.\\d+)?)?$");

RegEx Demo

(?=\.*\d) is the positive lookahead that ensures there is at least one digit thus making sure we don't match just .. as a valid input.

like image 123
anubhava Avatar answered Dec 21 '22 09:12

anubhava