# Why is this number matched with this regex?

The regex is -?([0-9]|([1-9][0-9])).

The number is -2231 and it's being matched. From my understanding, it should be a single digit or double digits.  Why is this number matched with this regex?

• It has 4 matches: See the explanation online. Feb 8, 2018 at 21:56
• A match can be found in the string, but it doesn't match the whole string. Feb 9, 2018 at 1:20
• @Jeff Schaller:  The original version of this question contained a regular expression in (ordinary, single) quotes, and you added back ticks without removing the quotes.  That makes it look like the single quotes are part of the regex that the OP is asking about, which makes the question very confusing. Feb 16, 2018 at 4:57
• Sorry for the confusion, @G-man. I’m accustomed to seeing regexes in quotes to protect them from shell interpretation. The number wouldn’t have matched a regex that required quote marks, but it’s better to be clear about things, so thank you for the improvement! Feb 16, 2018 at 11:00
• @Jeff Schaller:  Yeah, it occurred to me later that, if I had seen the regex in quotes in the context of a command line, it would have been perfectly clear. Feb 16, 2018 at 15:13

The regular expression is not anchored, so it's free to match the first 1 or two numbers and "succeed", leaving the trailing numbers (successfully) unmatched.

If you require 1 or 2 digit numbers, anchor the regex:

'^-?([0-9]|([1-9][0-9]))\$'

Some examples:

\$ seq -100 -99 | grep -E '^-?([0-9]|[1-9][0-9])\$'
-99

\$ seq 99 100 | grep -E '^-?([0-9]|[1-9][0-9])\$'
99

\$ seq -9 9  | grep -E '^-?([0-9]|[1-9][0-9])\$'
-9
-8
-7
-6
-5
-4
-3
-2
-1
0
1
2
3
4
5
6
7
8
9

\$ seq -2231 -100 | grep -E '^-?([0-9]|[1-9][0-9])\$'
(empty)
• See also the -x grep option to anchor the regexp at start and end. Feb 8, 2018 at 15:57
• Note that \$ anchors to end of line. If you want to anchor to the end of the "word", use \b (if that it supported by your regex flavor). Feb 8, 2018 at 18:31

Most programs that use regex patterns actually implement a search of the pattern, instead of a full-string match. Python has distinct search() and match() methods where search() matches anywhere in the string, and match() only at the beginning. grep has the -x option to demand a match against the whole string; by default it matches anywhere in the string. Others, like sed, awk and Perl will happily look for the pattern anywhere in the string. Use the ^ and \$ modifiers ("anchors") to force the pattern to the start or end of the string (respectively).

So, the ERE pattern you want is probably this:

^-?[1-9]?[0-9]\$
• See also expr that anchors at the start but not at the end (uses BREs though, not those EREs). Feb 8, 2018 at 16:17
• I like this answer because it explains that regular expressions can only be evaluated in the context in which they're used. Sometimes the regex must match the entire string, other times it must only be found somewhere within another string. The OP's question can't be answered without understand what program or function the regex is used within. Feb 8, 2018 at 22:12
• i just put the number in vi editor Feb 11, 2018 at 0:54