在我的正则表达式下面:
preg_match('/^[p{L}p{N} @]+$/u', $string);
我的目标是设置p{L}
, p{N}
, @
和整个字符串的最小和最大长度。我试图把{min, max}
在p{L}
和每个部分之后,但它不起作用。
您可以在需要重复的子模式之后使用限定词来设置模式的最小和最大长度。
这里我们需要使用一个技巧来确保我们可以计数非连续的子模式。它可以在开头使用负字符类和提前查找来完成。
下面是一个包含*至少4个字母的p{L}
,包含至少5个和6个最大数字的p{N}
,以及包含至少3个数字的@
的正则表达式的例子:
^(?=(?:[^np{L}]*p{L}){4}[^np{L}]*$)(?=(?:[^np{N}]*p{N}){5,6}[^np{N}]*$)(?=(?:[^n@]*@){3}[^n@]*$)[p{L}p{N} @]+$
这是一个演示
注意,如果您不打算使用多行模式(m
标志),可以删除n
。
这3个条件是内部的展望:
-
(?=(?:[^np{L}]*p{L}){4}[^np{L}]*$)
-这个向前看匹配(从输入字符串的开始)任何不是字母的序列,然后是一个字母4次(你可以在这里设置任何其他限制,然后寻找非字母直到结束(如果它找到更多,它失败)。 -
(?=(?:[^np{N}]*p{N}){5,6}[^np{N}]*$)
-类似的向前看,但现在,我们匹配非数字+数字5或6次,并确保以后没有数字。 -
(?=(?:[^n@]*@){3}[^n@]*$)
-@
相同的逻辑。
如果你只需要设置一个最小的阈值,你不需要那些否定的字符类在一个向前看的结束,例如(?=(?:[^n@]*@){3})
将匹配3个或更多的@
,它将只需要3个@
s。