Regex matches all but one digit
6 answers
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
+2
source to share