Reputation: 11886
What would be the regex to match — or not match — everything but a single digit?
For example,
stack
should matchstack overflow
should match12389237
should match but2
should not matchI’m on ^[^\d]+$
, but apparently it doesn't match my third condition.
EDIT:
This is for PHP by the way.
Upvotes: 3
Views: 3470
Reputation: 7804
Is it have to be regex ? For php you do like this
is_integer($string) && $string < 10
Upvotes: 1
Reputation: 80415
The easiest is simply to negate a match for a lone digit using normal program logic:
! /(?<!\d)\d(?!\d)/
Encoding that in a single pattern in possible, but annoying:
/^(?!.*(?<!\d)\d(?!\d))/
or spread out via /x
:
/ ^ (?! .* (?<! \d) \d (?! \d) )/x
Or insulated against various multiline circumstances:
/ \A (?! .* (?<! \d) \d (?! \d) )/sx
See why I said negating a regular positive match is easier?
Here’s the 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
Which produces:
PASS: "stack" should match
PASS: "stack overflow" should match
PASS: "12389237" should match but
FAIL: "2" should not match
If you misformatted your question, and if you simply meant that the the strings are actually
stack
stack overflow
12389237
2
instead, then the simple thing to do is still to negate the match against a single digit:
! /^\d$/
or more carefully,
! /\A\d\z/
Building the ɴᴏᴛ operation into the pattern 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
Upvotes: 2
Reputation: 4367
The following regex will match a string (including the whitespace), and any number that is not a single digit:
/^[a-zA-z\s]+|[0-9]{2,}$/gm
Upvotes: 0
Reputation: 83
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
stack overflow match
12389237 match
2 NOT match
Upvotes: 0
Reputation: 33918
Not match a single digit, inverting the match:
!/^\d\z/
Or just regex with a negative lookahead:
/^(?!\d\z)/
Upvotes: 2
Reputation: 6178
Break it down into two cases. Either match a single character that isn't a digit, or match any string of length 2 or greater:
^(\D|.{2,})$
Upvotes: 4