在Unicode正则表达式中为特定字符类部件设置长度限制

时间:2015-07-21 07:42:05

标签: php regex preg-match

在我的法律表达下面:

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

我的目标是设置\p{L}\p{N}@的最小和最大长度以及整个字符串。我试图在{min, max}之后和\p{L}之后放置{{1}}但是它不起作用。

1 个答案:

答案 0 :(得分:1)

您可以在需要重复的子模式之后,在限制量词的帮助下将最小和最大长度设置为模式。

这里我们需要使用一个技巧来确保我们可以计算非连续的子模式。它可以用负面的角色类和开头的前瞻来完成。

以下是*至少4个字母\p{L}的正则表达式示例,至少5个和6个最大数字\p{N},以及至少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} @]+$

这是demo

请注意,如果您不打算使用多行模式(\n标志),则可以删除m

这三个条件是内部预测:

  • (?=(?:[^\n\p{L}]*\p{L}){4}[^\n\p{L}]*$) - 此前瞻符合(从输入字符串的开头)任何不是字母的序列,然后是4次字母(您可以在此处设置任何其他限制,然后查找非字母到达结束(如果发现更多,则失败)。
  • (?=(?:[^\n\p{N}]*\p{N}){5,6}[^\n\p{N}]*$) - 类似的前瞻,但现在,我们将非数字+数字匹配5或6次,并确保以后没有数字。
  • (?=(?:[^\n@]*@){3}[^\n@]*$) - 与@相同的逻辑。

如果您只需要设置一个最小阈值,那么在前瞻的末尾不需要那些否定的字符类,例如: (?=(?:[^\n@]*@){3})将匹配3个或更多@,只需要3个@