2013-10-12 3 views
-1

Я пытаюсь сопоставить шаблон i2, 3 цифры и затем штрих - и от 1 до 3 цифр.Получение номера и ограничение шаблона

Пример данных

i2123-1 
i2121-20 
i2111-331 
i2111 
i21111 
i2111-1141 

должны соответствовать только

i2123-1 
i2121-20 
i2111-331 

Я попытался это, но его не соответствие некоторых моделей, и для некоторых это соответствует слишком много.

preg_match_all('/i2\d{3}-\d{3}/', $str, $matches); 
+0

'/ i2 \ d {3} - \ d {3} /' не соответствует 'too much', он соответствует верхнему пределу цифр после '-'. Это либо соответствует, либо нет, нет слишком мало или слишком много. Если возникают проблемы с символами 'before' и' after', они должны быть специально указаны – sln

ответ

1

Вы должны изменить ваш последний \d{3} к \d{1,3} принять 1 до 3 числа после тире. Но даже тогда вы все равно будете соответствовать больше, чем хотите, я использовал бы границу слова \b для этого конкретного случая.

preg_match_all('/\bi2\d{3}-\d{1,3}\b/', $str, $matches); 

См live demo

0

Вам просто нужно сделать квантор принимать менее, используя формат {m,n} и использовать границу слова:

/i2\d{3}-\d{1,3}\b/ 

или, наоборот, отрицательный предпросмотр или якорь (если вы не хотите соответствовать i2123-123-):

/i2\d{3}-\d{1,3}(?!.)/ 

/i2\d{3}-\d{1,3}$/  

Вы, вероятно, потребуется режим многострочный для последнего:

preg_match_all('/i2\d{3}-\d{1,3}$/m', $str, $matches); 

regex101 demo

Если вы хотите быть абсолютно уверены, что нет ничего в этой модели, использовать анкеры и режим многострочный (если вы дополнительно тестируют несколько строк в одну строку:

preg_match_all('/^i2\d{3}-\d{1,3}$/m', $str, $matches); 
0

Я считаю, что правильное решение необходимо включить \b в начале картины, так что я хотел бы использовать

preg_match_all('/\bi2\d{3}-\d{1,3}\b/', $str, $matches); 

Тестовые это и другие решения, размещенные против этого входа образца:

i2123-1 
i2121-20 
i2111-331 
i2111 
i21111 
i2111-1141 
i2123-1 
1i2121-20 
ai2111-331 

Смотреть это demo.

Смежные вопросы