2

What's the regex for validating input for this

Below 3 line are valid

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

Below lines are Invalid strings

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

I tried this

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

}

I can split and can validate like something like below , but I want to do this by single regex

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

Input can be just prefixed by PROJ and 4 digit number

PROJ9450

OR

Input can be prefixed by PROJ and 4 digit number - prefixed by PROJ and 4 digit number like this upto n

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

OR

Input can be prefixed by PROJ and 4 digit number undescore digit - prefixed by PROJ and 4 digit number underscore digit like this upto n

PROJ9400_1-PROJ9400_2-PROJ9401_1-PROJ9402_1 ... PROJ{n}_{n}

1
  • You should also show several invalid strings (and explain why). Commented Nov 9, 2016 at 14:35

1 Answer 1

4

You need to match the block starting with PROJ and followed with 4 digits (that are optionally followed with - or _ and 1+ digits) repeatedly.

Use

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

See the regex demo

Details:

  • ^ - start of string anchor
  • (PROJ[0-9]{4}(?:[-_][0-9]+)?) - Group 1 (that will be later recursed with (?1) recursion construct) capturing:
    • PROJ - a literal char sequence
    • [0-9]{4} - 4 digits
    • (?:[-_][0-9]+)? - an optional (1 or 0 occurrences) of
  • (?:-(?1))* - zero or more occurrences of - followed with Group 1 subpattern up to...
  • $ - end of string (better replace it with \z anchor that matches the very end of the string).
Sign up to request clarification or add additional context in comments.

3 Comments

Wow.. this is awesome... this is what I wanted recursion based.. Thank you so much
PROJ9450-1 should be false
Why should it be false? You should add it to the list of invalid inputs. Try ^(?!PROJ\d{4}[-_]\d+$)(PROJ\d{4}(?:[-_]\d+)?)(?:-(?1))*$. The (?!PROJ\d{4}[-_]\d+$) lookahead will fail all the strings similar to PROJ1234-12 or PROJ1234_12.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.