Regex matches all but one digit
What would be the regex to match - or not match - all but one digit?
For example,
-
stack
must match -
stack overflow
must match -
12389237
should match but -
2
shouldn't match
I'm on ^[^\d]+$
, but apparently it doesn't meet my third condition.
EDIT:
This is for PHP, by the way.
Break it down into two cases. Any of these matches a single character that is not a digit, or matches any string of length 2 or greater:
^(\D|.{2,})$
The easiest way is to simply negate the match for a single digit using normal programming logic:
! /(?<!\d)\d(?!\d)/
Coding what in one template is possible but annoying:
/^(?!.*(?<!\d)\d(?!\d))/
or expand through /x
:
/ ^ (?! .* (?<! \d) \d (?! \d) )/x
Or isolated from various multi-line circumstances:
/ \A (?! .* (?<! \d) \d (?! \d) )/sx
See why I said denying a regular positive match is easier?
Here's a test program:
use v5.12;
while (<DATA>) {
my $got = / ^ (?! .* (?<! \d) \d (?! \d) )/x;
print $got ? "PASS" : "FAIL";
print ": ", $_;
}
__END__
"stack" should match
"stack overflow" should match
"12389237" should match but
"2" should not match
What produces:
PASS: "stack" should match
PASS: "stack overflow" should match
PASS: "12389237" should match but
FAIL: "2" should not match
EDIT
If you misdiagnosed your question and if you just meant that the strings are actually
stack
stack overflow
12389237
2
instead, the simple thing then is to deny a single digit match:
! /^\d$/
or more carefully,
! /\A\d\z/
Constructing an operation ɴᴏᴛ in a template is never pretty.
/^ (?! \d $ )/x
Here's another test program:
use v5.12;
while (<DATA>) {
my $got = /^ (?! \d $ )/x;
print $got ? "PASS" : "FAIL";
print ": $_";
}
__END__
stack
stack overflow
12389237
2
which reports:
PASS: stack
PASS: stack overflow
PASS: 12389237
FAIL: 2
Doesn't match a single digit, inverting the match:
!/^\d\z/
Or just a negative regex:
/^(?!\d\z)/
Does it have to be a regular expression? For php you like this
is_integer($string) && $string < 10
The following regex will match a string (including space) and any number that is not a single digit:
/^[a-zA-z\s]+|[0-9]{2,}$/gm
RegExr Code
while(my $line = <DATA>){
chomp $line;
if ($line !~ /^\d{1}$/) {
print "$line match\n";
}
else {
print "$line NOT match\n";
}
}
__DATA__
stack
stack overflow
12389237
2
Result:
perl regex.pl
stack match
Qaru match
12389237 match
2 NOT match