你不能对锚点应用量词。相反,为了限制输入字符串的长度,请在开头使用一个以前瞻锚定的方式。
// ECMAScript (JavaScript, C++)
^(?=.{1,15}$)[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*$
^^^^^^^^^^^
// Or, in flavors other than ECMAScript and Python
\A(?=.{1,15}\z)[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*\z
^^^^^^^^^^^^^^^
// Or, in Python
\A(?=.{1,15}\Z)[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*\Z
^^^^^^^^^^^^^^^
另外,我猜你想要用
(a-z|A-Z|0-9)*
匹配零个或多个字母或数字。应该写成
[a-zA-Z0-9]*
(即在这里使用字符类)。
为什么不在末尾使用限定量词,比如 {1,15}
?
量词仅适用于左侧的子模式,无论是组、字符类还是文字符号。因此,^[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']{1,15}$
将有效地限制第二个字符类 [^$%^&*;:,<>?()\"']
的长度为 1 到 15 个字符。而 ^(?:[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*){1,15}$
将把长度不受限制的两个子模式的序列(因为 *
(以及 +
)可以匹配无限数量的字符)限制在 1 到 15 次,但我们仍未限制整个输入字符串的长度。
前瞻限制如何工作?
(?=.{1,15}$)
/
(?=.{1,15}\z)
/
(?=.{1,15}\Z)
这个
正向前瞻出现在
^
/
\A
(注意,在Ruby中,
\A
是唯一只匹配整个字符串开头的锚点)即字符串开头的位置。它是一个
零宽断言,在检查其子模式是否与后续字符匹配后,仅返回true或false。因此,这个前瞻尝试匹配任意1到15个字符(由于
限定量词{1,15}
),但不能匹配字符串末尾的换行符(由于
$
/
\z
/
\Z
锚点)。如果我们从前瞻中移除
$
/
\z
/
\Z
锚点,前瞻将只要求字符串
包含1到15个字符,而总字符串长度可以是任意的。
如果输入字符串可能包含换行序列,您应该使用
[\s\S]
可移植任意字符正则表达式构造(它适用于JS和其他常见的正则表达式风格):
// ECMAScript (JavaScript, C++)
^(?=[\s\S]{1,15}$)[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*$
^^^^^^^^^^^^^^^^^
// Or, in flavors other than ECMAScript and Python
\A(?=[\s\S]{1,15}\z)[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*\z
^^^^^^^^^^^^^^^^^^
// Or, in Python
\A(?=[\s\S]{1,15}\Z)[a-zA-Z0-9]*[^$%^&*;:,<>?()\"']*\Z
^^^^^^^^^^^^^^^^^^