2014-11-12 3 views
4

Возьмем следующее регулярное выражение:Regex потерпеть неудачу, если несколько совпадений найдено

P[0-9]{6}(\s|\.|,) 

Это предназначен для проверки на 6 значное число, которому предшествует «P» в строке - отлично работает по большей части.

Проблема в том, что нам нужно сбой если найдено более одного совпадения - возможно ли это?

т.е. сделать текст 4 в следующем скриншоте неудачу, но по-прежнему держать все другие неудачу/проходя, как показано ниже:

enter image description here

(это регулярное выражение выполняется в SQL .NET CLR)

+0

ли это поддержка взглядов? – vks

+0

После вашего поиска сделайте негативный прогноз с такими же критериями: (?!. * P [0-9] {6} (\ s | \. |,)) – OnlineCop

+0

@OnlineCop: После этого недостаточно. –

ответ

5

Если регулярное выражение двигатель, используемый этим инструментом действительно .NET двигатель, то вы можете использовать

^(?:(?!P[0-9]{6}[\s.,]).)*P[0-9]{6}[\s.,](?:(?!P[0-9]{6}[\s.,]).)*$ 

Если это родной SQL двигатель, й ru вы не можете сделать это с помощью одного регулярного выражения, потому что эти движки не поддерживают поисковые запросы.

Объяснение:

^       # Start of string 
(?:      # Start of group which matches... 
(?!P[0-9]{6}[\s.,])  # unless it's the start of Pnnnnnn... 
.      # any character 
)*      # any number of times 
P[0-9]{6}[\s.,]   # Now match Pnnnnnn exactly once 
(?:(?!P[0-9]{6}[\s.,]).)* # Match anything but Pnnnnnn 
$       # until the end of the string 

Попробуй live on regex101.com.

+0

Кроме того, если вы добавили бит '(\ s \ \. \), Который можно сократить до' [\ s.,] '), Чтобы убедиться, что число заканчивается там, вы можете использовать [слово граничный якорь] (http://www.regular-expressions.info/wordboundaries.html) '\ b'. –

+0

Это потрясающе - неудивительно, что я не мог понять это, хотя ясный, как грязь :) Не могли бы вы сделать быстрый пример, используя якорь границы границы? – HeavenCore

+1

Конечно: '^ (? :(?! P [0-9] {6} \ b).) * P [0-9] {6} \ b (? :(?! P [0-9] { 6} \ б).) * $ '. Обратите внимание, что 'P1234567 P123456' * будет * совпадать с обоими регулярными выражениями, потому что только одно из этих чисел составляет ровно 6 цифр. Если вы не хотите, чтобы это произошло, используйте '^ (? :(?! P [0-9] {6}).) * P [0-9] {6} \ b (? :(?! P [0-9] {6}).) * $ '. –

0

или использовать этот шаблон

^(?!(.*P[0-9]{6}[\s.,]){2})(.*P[0-9]{6}[\s.,].*)$ 

Demo
в основном проверить, если шаблон существует и не повторяется дважды.

^    Start of string 
(?!    Negative Look-Ahead 
    (   Capturing Group \1 
    .   Any character except line break 
    *   (zero or more)(greedy) 
    P   "P" 
    [0-9]   Character Class [0-9] 
    {6}   (repeated {6} times) 
    [\s.,]   Character Class [\s.,] 
)    End of Capturing Group \1 
    {2}   (repeated {2} times) 
)    End of Negative Look-Ahead 
(    Capturing Group \2 
    .    Any character except line break 
    *    (zero or more)(greedy) 
    P    "P" 
    [0-9]   Character Class [0-9] 
    {6}   (repeated {6} times) 
    [\s.,]   Character Class [\s.,] 
    .    Any character except line break 
    *    (zero or more)(greedy) 
)    End of Capturing Group \2 
$    End of string 
Смежные вопросы