4

Examples:

01  =  match
10  =  match
99  =  match
00  =  no match

So far I have this: /^ [1-9][0-9] | [0-9][1-9] $/ but I have the feeling it can be optimized.

Alex Crist
  • 1,059
  • 2
  • 12
  • 22

2 Answers2

11

You may use a negative lookahead to restrict a generic [0-9]{2} pattern:

^(?!00)[0-9]{2}$

See the regex demo

The [0-9]{2} will match exactly 2 digits. The (?!00) negative lookahead will be executed once at the beginning of the string and will make sure there are no 00 until the string end. If the string equals to 00, no match will be found.

See more at How Negative Lookahead Works.

A detailed pattern explanation:

  • ^ - start of string
  • (?!00) - a negative lookahead that fails the match if there are two 0s right after the current position (at the beginning of the string). Since the next subpattern - [0-9]{2}$ - only allows 2 symbols in the string, we do not have to add any anchor into the lookahead, in other scenarios, it is a must to add $ to just exclude 00 match.
  • [0-9]{2} - exactly two (thanks to the limiting quantifier {min(,max)?}) digits (in most flavors, [0-9] can be replaced with \d, but that \d can also match more than regular [0123456789] in some of the flavors)
  • $ - end of string (depending on the regex flavor, \z can be preferable as it matches the very end of string).
Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
2

Try this RegEx:

(?!00)\d\d

Live Demo on Regex101

This uses a Negative Lookahead (here is a nice answer explaining it), (?! ). This means is whatever is inside exists, do not match. In this case, it will detect if there are 00, and fail if there are. If not, select 2 digits (\d is shorthand for [0-9])


A safer version:

^(?!00)\d\d$

Live Demo on Regex101

This also uses ^, which states that the data must be at the start of the string (or line with the m flag), and $ the data must be at the end. Therefore when you use ^ $, the data inside must match the full line / string


Here are some examples of Negative Lookahead:

# Using the RegEx (?!9)\d
1    # Match
2    # Match
5    # Match
9    # NO MATCH

# Using the RegEx (?!Tom)\w+
Tim    # Match
Joe    # Match
Bob    # Match
Tom    # NO MATCH

# Using the RegEx (?!Foo)\w+(?!Bar)
BarBazFoo    # Match
BazBarFoo    # Mtach
FooBarBaz    # NO MATCH
BazFooBar    # NO MATCH
Community
  • 1
  • 1
Kaspar Lee
  • 5,446
  • 4
  • 31
  • 54
  • `(?!00)\d\d` will also match `99` in `9900`. – Wiktor Stribiżew Apr 05 '16 at 12:48
  • @WiktorStribiżew I thought there would only be 2 digits, especially since you used `{2}` in your answer. If there are, then `9900` will never exist. But thanks for informing me! – Kaspar Lee Apr 05 '16 at 12:53
  • A limiting quantifier does not indicate how many characters there should be in the input, but how many the previous subpattern can match. – Wiktor Stribiżew Apr 05 '16 at 12:54
  • @WiktorStribiżew I am aware of that, but your RegEx will only match if there are 2 digits. I concluded that because of the `{2}` – Kaspar Lee Apr 05 '16 at 12:55
  • It will match only 2 digit strings/lines because I deduced that from the original pattern :) – Wiktor Stribiżew Apr 05 '16 at 13:01
  • @WiktorStribiżew That was basically what I concluded. Just wh yin your first comment did you mention that it will match `99` in `9900`, since `9900` will never exist, so it is not relevant – Kaspar Lee Apr 05 '16 at 13:03