问题描述
我正在尝试使用以下正则表达式来验证生日:
I am trying to validate birthdays using the following regex:
^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
此正则表达式在在线正则表达式测试器中进行测试时有效,但是当我尝试在我的Firebase规则中使用此正则表达式时,Firebase似乎不接受它.我还尝试将反斜杠加倍,但仍然没有运气.
This regex works when tested in an online regex tester, but when I try to use this regex inside my firebase rules, Firebase seems to not accept it. I also tried doubling my backslashes and still no luck.
这是我的Firebase规则:
This is my firebase rule:
".validate": "newData.isString() && newData.val().matches(/^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/)"
这是我在Firebase上遇到的错误:非法正则表达式,未转义的^,^只能出现在正则表达式的末尾"
This is the error I get on Firebase: "Illegal regular expression, unescaped ^, ^ can only appear at the end of regular expressions"
如何调整此正则表达式使其在Firebase上运行?
How can I tweak this regex to get it working on Firebase?
推荐答案
您需要在此处做两件事:
You need to do two things here:
- 确保所有反斜杠都加倍
- 将所有非捕获组都变为捕获组,然后重新调整后向引用(请注意,应删除多余的捕获组)(请注意,您不能使用
\ 15
作为后向引用,这似乎只是支持1到9个反向引用) - 重新配置模式,以使字符串锚的
^
开头出现在正则表达式的开头,而$
仅出现在正则表达式的结尾(否则,您将得到非法的正则表达式例外).这里的操作很容易,因为您的模式是^ a1 $ | ^ a2 $ | ^ a3 $
类型,并且它等于^(?: a1 | a2 | a3)$
.
- make sure all backslashes are doubled
- turn all non-capturing groups into capturing ones and re-adjust the backreferences (note that redundant capturing groups should be eliminated) (note you can't use
\15
as backreference, it seems only 1 to 9 backreferences are supported) - re-vamp the pattern so that the
^
start of string anchor appeared at the beginning and$
only at the end of the regular expression (otherwise, you will get the illegal regex exception). It is easy to do here as your pattern is of the^a1$|^a2$|^a3$
type, and it is equal to^(?:a1|a2|a3)$
.
图案应该看起来像
newData.val().matches(/^((31([-\\/.])(0?[13578]|1[02])\\3|(29|30)([-\\/.])(0?[13-9]|1[0-2])\\6)(1[6-9]|[2-9]\\d)?\\d{2}|29([-\\/.])0?2\\9((1[6-9]|[2-9]\\d)?(0[48]|[2468][048]|[13579][26])|(16|[2468][048]|[3579][26])00)|(0?[1-9]|1\\d|2[0-8])([-\\/.])(0?[1-9]|1[0-2])[-\\/.](1[6-9]|[2-9]\\d)?\\d{2})$/)
请注意,我也将(\/|-| \ ..)
转换为([-\/.])
(因为字符类比普通字符类更有效并使用单字符替代形式),并从 [1,3-9]
中删除逗号-看起来像是一个错字,您想匹配 1
或 3 到 9
,而
在字符类中按字面意义处理.
Note that I also turned (\/|-|\.)
into ([-\/.])
(since a character class is more efficient than plain alternation with single-char alternatives) and remove a comma from [1,3-9]
- it looks like a typo, you wanted to match 1
or a digit from 3
to 9
, I believe, and a ,
is treated literally in a character class.
这篇关于Firebase规则正则表达式生日的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!