php - Set length limits to specific character class parts in Unicode regular expression -


below regual expression:

preg_match('/^[\p{l}\p{n} @]+$/u', $string); 

my goal set minimum , maximum length of \p{l}, \p{n}, @ , whole string. tried putting {min, max} after \p{l} , after each part doesn't work.

you can set min , max length pattern of limiting quantifiers right after subpattern need repeat.

here need use trick make sure can count non-consecutive subpatterns. can done negative character classes , look-aheads in beginning.

here example of regex *at least 4 letters \p{l}, @ least 5 , 6 max numbers \p{n}, , @ least 3 @:

^(?=(?:[^\n\p{l}]*\p{l}){4}[^\n\p{l}]*$)(?=(?:[^\n\p{n}]*\p{n}){5,6}[^\n\p{n}]*$)(?=(?:[^\n@]*@){3}[^\n@]*$)[\p{l}\p{n} @]+$ 

here demo

note \n can removed if not planning use multiline mode (m flag).

the 3 conditions inside look-aheads:

  • (?=(?:[^\n\p{l}]*\p{l}){4}[^\n\p{l}]*$) - lookahead matches (from beginning of input string) sequence not letters , letter 4 times (you may set other limits here, , looks non-letters end (if finds more, fails).
  • (?=(?:[^\n\p{n}]*\p{n}){5,6}[^\n\p{n}]*$) - similar lookahead, now, matching non-digits + digit 5 or 6 times, , make sure there no numbers later.
  • (?=(?:[^\n@]*@){3}[^\n@]*$) - same logic @.

if need set minimum threshold, not need negated character classes @ end of lookahead, e.g. (?=(?:[^\n@]*@){3}) match 3 or more @, require 3 @s.


Comments