ObiHill
ObiHill

Reputation: 11886

Regex to match everything but a single digit

What would be the regex to match — or not match — everything but a single digit?

For example,

I’m on ^[^\d]+$, but apparently it doesn't match my third condition.

EDIT:

This is for PHP by the way.

Upvotes: 3

Views: 3470

Answers (6)

safarov
safarov

Reputation: 7804

Is it have to be regex ? For php you do like this

is_integer($string) && $string < 10

Upvotes: 1

tchrist
tchrist

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

EDIT

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

PenguinCoder
PenguinCoder

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

RegExr Code

Upvotes: 0

nyet
nyet

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

Qtax
Qtax

Reputation: 33918

Not match a single digit, inverting the match:

!/^\d\z/

Or just regex with a negative lookahead:

/^(?!\d\z)/

Upvotes: 2

VeeArr
VeeArr

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

Related Questions