Регулярное выражение для сопоставления всего, кроме одной цифры


Каким будет регулярное выражение, чтобы соответствовать - или не соответствовать-всему, кроме одной цифры?

Например,

  • stack должно соответствовать
  • stack overflow должно соответствовать
  • 12389237 должно соответствовать но
  • 2 должен не соответствовать
Я нахожусь на ^[^d]+$, но, по-видимому, это не соответствует моему третьему условию.

Редактировать:

Кстати, это для PHP.

6 3

6 ответов:

Разбейте его на два случая. Либо сопоставьте один символ, который не является цифрой, либо любую строку длиной 2 или больше:

^(\D|.{2,})$

Не совпадают ни с одной цифрой, инвертируя совпадение:

!/^\d\z/

Или просто регулярное выражение с отрицательным lookahead:

/^(?!\d\z)/

Проще всего просто отрицать совпадение для одной цифры, используя обычную программную логику:

 ! /(?<!\d)\d(?!\d)/

Кодирование, которое в единственном шаблоне возможно, но раздражает:

/^(?!.*(?<!\d)\d(?!\d))/

Или разложить через /x:

/ ^ (?! .* (?<! \d) \d (?! \d) )/x

Или изолированные от различных многострочных обстоятельств:

 / \A (?! .* (?<! \d) \d (?! \d) )/sx

Видите, почему я сказал, что отрицание регулярного положительного совпадения легче?

Вот тестовая программа:

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

Который производит:

PASS: "stack" should match
PASS: "stack overflow" should match
PASS: "12389237" should match but
FAIL: "2" should not match

EDIT

Если вы неправильно сформулировали свой вопрос, и если вы просто имели в виду, что строки на самом деле

stack
stack overflow
12389237
2

Вместо этого, тогда самое простое, что нужно сделать, это все еще отрицать совпадение с одной цифрой:

! /^\d$/

Или более осторожно,

! /\A\d\z/

Построение операции ɴᴏᴛ в шаблон никогда не бывает красивым.

/^ (?! \d $ )/x

Вот еще одна тестовая программа:

use v5.12;
while (<DATA>) {
    my $got =  /^ (?! \d $ )/x;
    print $got ? "PASS" : "FAIL";
    print ": $_";

}
__END__
stack
stack overflow
12389237
2

Который сообщает:

PASS: stack
PASS: stack overflow
PASS: 12389237
FAIL: 2

Обязательно ли это регулярное выражение ? Для php вы делаете вот так

is_integer($string) && $string < 10
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

Результат:

perl regex.pl
stack   match
stack overflow  match
12389237        match
2       NOT match

Следующее регулярное выражение будет соответствовать строке (включая пробел) и любому числу, которое не является одной цифрой:

/^[a-zA-z\s]+|[0-9]{2,}$/gm

Код RegExr