在 Realtime Database 安全规则中使用正则表达式

正则表达式字面值可用于验证客户端提供的字符串。使用 string.matches(/pattern/) 测试字符串是否符合正则表达式模式。该正则表达式语法与常见的正则表达式语法并不完全相同,具体而言:

  • * + . ( ) [ ] { } \ 正常运行。
  • 只有在用于匹配模式中的第一个或最后一个字符时,^$ 定位点才有效。
  • 仅支持 i(忽略大小写)修饰符标志

字面量

使用 /pattern/ 表示法将正则表达式字面值引入到安全表达式中。如需测试字符串是否符合正则表达式模式,请使用字符串的 matches 成员函数。以下匹配规则会检查新数据是否以字符串“foo”开头。

".validate": "newData.val().matches(/^foo/)"

支持的功能

Firebase 仅支持部分典型的正则表达式功能。不过,正则表达式语法应该会让人感到熟悉。

以下是支持的符号:

角色 含义
\s \w \d \S \W \D 用于匹配空格、字词字符或数字的预定义字符集及其否定形式(分别)
\ 转义,后面的字符按字面意思解读。
如果您想匹配“”,也需要对其进行转义 /\/
^ 锚定到字符串的开头。只能用作模式的第一个字母。
/a/ 匹配“ba”,而 /^a/ 不匹配。
$ 锚定到字符串末尾。只能用作模式的最后一个字母。
/a/ 匹配“ab”,而 /a$/ 不匹配。
* 匹配零个或多个前面的模式。
/^a*$/ 匹配“”和“aaa”,但不匹配“b”
+ 匹配一个或多个前面的模式。
/^a+$/ 匹配“a”和“aaa”,但不匹配空字符串
? 匹配零个或一个前面的模式。
/^a?$/ 匹配“”和“a”,但不匹配“aa”
. 匹配任何字符
/......../ 匹配“Firebase”
(pattern) 圆括号将模式分组为一个单元
/(ab)*/ 与“abab”匹配
a|b 匹配 a 或 b
/a|bc/ 匹配“ac”或“bc”
[akz] 一个字符集,匹配其中包含的任何字符。
/[ABCDEF]/ 仅匹配大写字母 A 到 F。
[a-z] 一个字符区间,匹配指定范围内的所有字符(包括端点)。
/[0-9A-F]+/ 匹配十六进制字符串
[^0-9] 开头的 ^ 会否定字符集,匹配指定字符集以外的任何内容。

正则表达式字面量构造(例如 /yes/i)后面的 i 表示匹配不区分大小写。目前不支持其他正则表达式修饰符。

Firebase Realtime Database 安全规则中的正则表达式匹配既不是贪婪的,也不是非贪婪的,因为它只允许您检测匹配项,而不允许捕获字符串的某些部分。

用法

要求字符串为 YYYY-MM-DD 格式的日期,且介于 1900 年至 2099 年之间:

".validate": "newData.isString() && newData.val().matches(/^(19|20)[0-9][0-9][-\\/. ](0[1-9]|1[012])[-\\/. ](0[1-9]|[12][0-9]|3[01])$/)"

要求字符串为电子邮件地址:

".validate": "newData.isString() && newData.val().matches(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i)"

要求字符串为基本网址:

".validate": "newData.isString() && newData.val().matches(/^(ht|f)tp(s?):\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*((0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\+&=%\\$#_]*)?$/)"