Самое простое - просто отменить совпадение для одиночной цифры, используя обычную программную логику:
! /(?<!\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
РЕДАКТИРОВАТЬ
Если вы неправильно отформатировали свой вопрос, и если вы просто имели в виду, чтостроки на самом деле
stack
stack overflow
12389237
2
, тогда самое простое, что нужно сделать, это отменить совпадение с одной цифрой:
! /^\d$/
или, более осторожно,
! /\A\d\z/
Встраивание операции into в шаблон никогда не бывает приятным.
/^ (?! \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