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?

  • 2
    It has 4 matches: See the explanation online. – Thomas Weller Feb 8 at 21:56
  • 5
    A match can be found in the string, but it doesn't match the whole string. – martin Feb 9 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. – G-Man Feb 16 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! – Jeff Schaller Feb 16 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. – G-Man Feb 16 at 15:13
up vote 21 down vote accepted

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. – Stéphane Chazelas Feb 8 at 15:57
  • 4
    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). – user3067860 Feb 8 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). – Stéphane Chazelas Feb 8 at 16:17
  • 5
    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. – Randall Stewart Feb 8 at 22:12
  • i just put the number in vi editor – Rashad Feb 11 at 0:54

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.