2016-11-09 77 views
2

的多個occurence什麼是正則表達式驗證輸入此PHP的正則表達式來驗證輸入

以下3行是有效

PROJ9450 
PROJ9400-PROJ9401-PROJ9402 ..... PROJ{n} 
PROJ9400_1-PROJ9400_2-PROJ9401_1-PROJ9402_1-PROJ9408 ... PROJ{n}_{n} 

以下行是無效的字符串

PROJ450 
PRO1223 
PROJ9400a-PROJ9401-PROJ9400-PROJ1929-1-PROJ1929 
PROJ9400_1-PROJ9400_2-PROJ9401_1-PROJ9402_1-PROJs453 ... PROJ{n}_{n} 

我想這

if(preg_match('/(PROJ)[0-9]{4}(-|_)?[0-9]+)/', $input)) 
{ 

} 

我可以分割並且可以驗證像類似下面,但我想通過單一的正則表達式來做到這一點

foreach(explode('-',$input) as $e) 
{ 
     if(!preg_match('/(PROJ)[0-9]{4}(-|_)?[0-9]+)/', $e)) 
     { 
      return 'Invalid Input'; 
     } 
} 

輸入可以通過PROJ只是前綴和4位數字

PROJ9450

輸入可以前綴PROJ和4位數字 - 前綴PROJ和d 4位數字,如本高達n

PROJ9400-PROJ9401-PROJ9402 ..... PROJ {N}

OR

輸入可以通過PROJ前綴和4位數字undescore數字 - 通過PROJ和4位數字前綴強調這樣數字高達 n

PROJ9400_1-PROJ9400_2-PROJ94 01_1-PROJ9402_1 ... PROJ {N} _ {N}

+0

您還應該顯示幾個無效的字符串(並解釋原因)。 –

回答

4

您需要匹配塊開始PROJ和隨後用4個數字(被任選地接着與-_和1+位數)反覆

使用

/^(PROJ[0-9]{4}(?:[-_][0-9]+)?)(?:-(?1))*$/ 

regex demo

詳細

  • ^ - 字符串的開始anchor
  • (PROJ[0-9]{4}(?:[-_][0-9]+)?) - 第1組(將在後面用遞歸(?1)recursion construct)捕獲:
    • PROJ - 的 任選(1或0次)
      • [-_] - - 文字字符序列
      • [0-9]{4} - 4位數字
      • (?:[-_][0-9]+)?一個character class匹配-_
      • [0-9]+ - 1位或更多位
  • (?:-(?1))* - 零個或多個出現-隨後與第1組的子模式最多...
  • $ - 字符串的結尾(更好地\z錨該字符串的末尾匹配替換) 。
+0

哇..這真棒...這就是我想要的遞歸基礎..非常感謝你 – user3637224

+0

PROJ9450-1應該是假的 – user3637224

+0

爲什麼它應該是假的?您應該將其添加到無效輸入列表中。試試[':^(?! PROJ \ d {4} [-_] \ d + $)(PROJ \ d {4}(?:[-_] \ d +)?)(?:-(?1))* $'](https://regex101.com/r/MHUBfi/3)。 '(?!PROJ \ d {4} [-_] \ d + $)'lookahead將失敗所有類似於'PROJ1234-12'或'PROJ1234_12'的字符串。 –