regex - Using regular expressions to validate a numeric range -


my input number int. input number must in range -2055 2055 , want check using regular expression.

so there anyway write regular expression check whether number in (-2055, 2055) or not ?

it easier use if statement check whether number in range or not. i'm writing interpreter should use regex check input number

using regular expressions validate numeric range

to clear: when simple if statement suffice

if(num < -2055  ||  num > 2055)  {    throw  new illegalargumentexception("num (" + num + ") must between -2055 , 2055"); } 

using regular expressions validating numeric ranges not recommended.

in addition, since regular expressions analyze strings, numbers must first translated string before can tested. exception when number happens string, such when getting user input console.

(to ensure string number begin with, use org.apache.commons.lang3.math.numberutils#isnumber(s))

despite this, figuring out how validate number ranges regular expressions interesting , instructive.

(the links in answer come stack overflow regular expressions faq.)

a 1 number range

rule: number must 15.

the simplest range there is. regex match is

\b15\b 

word boundaries necessary avoid matching 15 inside of 8215242.

a 2 number range

the rule: number must between 15 , 16. here 3 possible regexes:

\b(15|16)\b \b1(5|6)\b \b1[5-6]\b 

(the groups required "or"-ing, non-capturing: \b(?:15|16)\b)

a number range "mirrored" around zero

the rule: number must between -12 , 12.

here regex 0 through 12, positive-only:

\b(\d|1[0-2])\b 

free-spaced:

\b(         //the beginning of word (or number), followed either    \d       //   digit 0 through 9 |           //or    1[0-2]   //   1 followed digit between 0 , 2. )\b         //the end of word 

making work both negative , positive simple adding optional dash @ start:

-?\b(\d|1[0-2])\b 

(this assumes no inappropriate characters precede dash.)

to forbid negative numbers, negative lookbehind necessary:

(?<!-)\b(\d|1[0-2])\b 

leaving lookbehind out cause 11 in -11 match. (the first example in post should have added.)

note: \d versus [0-9]

in order compatible regex flavors, \d-s should changed [0-9]. example, .net considers non ascii numbers, such in different languages, legal values \d. except in last example, brevity, it's left \d.

(with @timpietzcker)

three digits, first digit equal zero

rule: must between 0 , 400.

a possible regex:

(?<!-)\b([1-3]?\d{1,2}|400)\b 

free spaced:

   (?<!-)          //something not preceded dash    \b(             //word-start, followed either       [1-3]?       //   no digit, or digit 1, 2, or 3          \d{1,2}   //   followed 1 or 2 digits (between 0 , 9)    |               //or       400          //   number 400    )\b             //word-end 

another possibility should never used:

\b(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255|256|257|258|259|260|261|262|263|264|265|266|267|268|269|270|271|272|273|274|275|276|277|278|279|280|281|282|283|284|285|286|287|288|289|290|291|292|293|294|295|296|297|298|299|300|301|302|303|304|305|306|307|308|309|310|311|312|313|314|315|316|317|318|319|320|321|322|323|324|325|326|327|328|329|330|331|332|333|334|335|336|337|338|339|340|341|342|343|344|345|346|347|348|349|350|351|352|353|354|355|356|357|358|359|360|361|362|363|364|365|366|367|368|369|370|371|372|373|374|375|376|377|378|379|380|381|382|383|384|385|386|387|388|389|390|391|392|393|394|395|396|397|398|399|400)\b 

final example: 4 digits, mirrored around zero, not end zeros.

rule: must between -2055 , 2055

this question on stackoverflow.

regex:

(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\b 

regular expression visualization

debuggex demo

free-spaced:

(             //capture group entire number    -?\b             //optional dash, followed word (number) boundary    (?:20            //followed "20", followed 1 of           (?:5[0-5]        //50 through 55            |                  //or          [0-4][0-9])      //00 through 49       |                                         //or          1[0-9]{3}        //a 1 followed 3 digits       |                                         //or          [1-9][0-9]{0,2}  //1-9 followed 0 through 2 of digit       |                                         //or          (?<!-)0+         //one-or-more zeros *not* preceded dash    )                 //end "or" non-capture group )\b            //end number capture group, followed word-bound 

(with plasmapower , casimir et hippolyte debugging assistance.)

final note

depending on capturing, sub-groups should made non-capture groups. example, this:

(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1?[0-9]{1,3})\b) 

instead of this:

-?\b(20(5[0-5]|[0-4][0-9])|1?[0-9]{1,3})\b 

example java implementation

  import  java.util.scanner;   import  java.util.regex.matcher;   import  java.util.regex.pattern;   import  org.apache.commons.lang.math.numberutils; /**   <p>confirm user-input number valid number reading string testing numeric before converting it--this loops until valid number provided.</p>    <p>{@code java userinputnuminrangewregex}</p>  **/ public class userinputnuminrangewregex  {   public static final void main(string[] ignored)  {       int num = -1;      boolean isnum = false;       int irangemax = 2055;       //"": dummy string, reuse matcher      matcher mtchrnumnegthrpos = pattern.compile("(-?\\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\\b").matcher("");        {         system.out.print("enter number between -" + irangemax + " , " + irangemax + ": ");         string strinput = (new scanner(system.in)).next();         if(!numberutils.isnumber(strinput))  {            system.out.println("not number. try again.");         }  else if(!mtchrnumnegthrpos.reset(strinput).matches())  {            system.out.println("not in range. try again.");         }  else  {            //safe convert            num = integer.parseint(strinput);            isnum = true;         }      }  while(!isnum);       system.out.println("number: " + num);   } 

}

output

[c:\java_code\]java userinputnuminrangewregex enter number between -2055 , 2055: tuhet not number. try again. enter number between -2055 , 2055: 283837483 not in range. try again. enter number between -2055 , 2055: -200000 not in range. try again. enter number between -2055 , 2055: -300 number: -300 

original answer stackoverflow question

this serious answer fits specifications. similar @plasmapower's answer.

(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\b 

regular expression visualization

debuggex demo


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -