0

I'm sure this has been asked before and I did read through a lot of posts but nothing helped me. Since my regex knowledge is limited I thought I would ask for help.

I need to validate some user input (zip code format). Only certain characters are allowed: A, N, CC, ?, space ( ) and hyphen (-).

Sample Input Data

$input = "CC-XNNNNN", "ANNNNAAA", "AAAA NAA", "ANN ????"

Regex Pattern

$pattern = "(?:C{2})*|A*|N*|\?*|\-*|\ *"

PHP Code

if(preg_match('/' . $pattern . '/', $input))
{
 echo("pass<br>" . PHP_EOL);
}
else
{
 echo("fail<br>" . PHP_EOL);
}

I don't think I need to use anchors, because the allowed characters can be in any position. With the above code I get 'pass' but I should get 'fail' (X not allowed). I've looked this over so much I can't see the forest for the trees anymore.

Can anyone see what I've done wrong? OR is regex the wrong tool for this?

5
  • 1
    When it comes to regex, I suggest using an online service for testing such as regex101.com. If I put your pattern in there, I get an error message about the |? sequence being invalid Commented Feb 11, 2021 at 0:38
  • Do the letters you listed in your question represent something here, like A == alpha, N == numeric, or are these letters literals in your input? Commented Feb 11, 2021 at 0:40
  • @Chris Haas, I did use regex101.com and if I copy/paste my pattern I don't get any error message. But it never fails even when it should. Commented Feb 11, 2021 at 0:53
  • @Tangentially Perpendicular, yes they do but that's not what I want tested. I only want the user to enter the allowed valid characters I listed. Commented Feb 11, 2021 at 0:55
  • Thanks @CharlesEF, it was a formatting error between markdown and HTML. I made a quick demo of your code and they all appear to pass: 3v4l.org/QpiKQ Commented Feb 11, 2021 at 2:49

2 Answers 2

2

Could you please try following regex, written and tested with shown samples. Online demo of regex is: Regex online demo

^(?:[aA]|[nN]|[cC]{2}|\?|\s+|-)+$

Explanation: Adding detailed explanation for above.

^(?:       ##Starting a non capturing group from starting of value here.
[aA]       ##Checking if its either small a or capital A here.
|[nN]      ##OR if its N or n here.
|[cC]{2}   ##OR its c or C here with 2 occurrences.
|\?        ##Or its ? as a literal character.
|\s+       ##OR its one or more occurrences of spaces.
|-         ##OR its a dash
)+         ##Closing non capturing group and + will make sure only these characters follow
$          ##till end of the value.

Also I have matched characters with their small letter form also in case you don't need that we could change above to: ^(?:A|N|C{2}|\?|\s+|-)+$ then.

Sign up to request clarification or add additional context in comments.

5 Comments

I've only had time for a small amount of testing. I tried with your pattern (the one with no lowercase). I've found 1 problem with my 4th input sample (ANN ????). Your pattern reports 'fail' when it should be 'pass'. I tried adding *, to allow for zero or many but that didn't work.
@CharlesEF, I have checked by putting ANNN ???? and it worked fine for me see this once regex101.com/r/ugdAzn/1 let me know how it goes for you, thank you.
Yes, it appears to work there but it reports 'fail' when I use my PHP code posted above. I will look into it more and report back later. Thanks for the help.
@CharlesEF, your welcome, cheers and happy learning
I found the problem. It was the space character. I copy/pasted from Excel into my editor but who knows what happened. In my editor I backspaced and then hit the space bar. Now it passes the test. Thanks again.
1

You could also use a character class instead of alternating between the single characters.

To also match the lowercase variant, you can use the /i flag

^(?:[AN? -]|CC)+$

The pattern matches:

  • ^ Start of string
  • (?: Non capture group
    • [AN? -] Match one of the listed characters
    • | Or
    • CC Match CC
  • )+ Close the group and repeat it 1+ times
  • $ End of string

Regex demo

1 Comment

Thanks for your solution, it appears to work just as well as RavinderSingh13's answer. He helped me first so he got the credit. Thank you for your input.

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.