如何在JSF中正确适配可正常运行的URL校验正则表达式
正则在JSF环境失效的核心原因
- 底层引擎差异:
f:validateRegex的校验逻辑底层基于Java正则引擎,而非JavaScript正则引擎,两者转义规则不通用:- JS场景下为适配正则字面量的包裹语法,需要对斜杠做
\/\/形式的转义,但Java正则中斜杠是普通字符,单写转义会直接导致匹配偏差 - Java字符串传入
Pattern.compile()方法时,所有用于正则规则的反斜杠需要双写(即\\),单写的反斜杠会被Java字符串解析层吃掉,无法形成有效正则匹配规则——比如单写\w最终会被解析成普通字符w,完全失去单词匹配的作用
- JS场景下为适配正则字面量的包裹语法,需要对斜杠做
- 多层转义叠加冲突:JSF页面本身是XML结构,标签属性值需要经过XML实体解析层,规则与JS字符串的转义规则不互通:
- XML属性值中必须对
&、<、"做实体转义(即转成&、<、"),如果直接写&会被XML解析器识别成实体开头,导致解析报错或者字符截断 - 多层转义如果混叠(同时叠加JS转义、Java转义、XML转义),会导致最终生效的正则规则和预期完全不一致
- XML属性值中必须对
- 原正则逻辑瑕疵:原字符类
(\w#!:.?+=&%!\-\/])中,连字符的转义位置容易触发正则范围匹配歧义,斜杠的冗余转义在Java正则中完全无效;同时Java正则默认是子串匹配,没有首尾锚点的情况下,任意包含匹配片段的输入都能通过校验。
适配编写步骤
- 第一步:基于Java正则规则调整转义,去掉JS场景下冗余的斜杠转义,将所有正则需要用到的反斜杠双写,保证Java字符串解析后能形成正确的正则规则
- 第二步:适配XML属性的实体转义要求,仅对XML规定必须转义的特殊字符做实体转义,不额外添加无意义的转义符——比如将规则里的
&转成&即可 - 第三步:修正字符类的歧义问题,将字符类里的连字符调整到类的最末端,避免被识别成字符范围分隔符,去掉冗余的转义符
- 第四步:为正则补全首尾匹配边界
^和$,实现输入内容的全量匹配,避免子串匹配的校验漏洞 - 第五步:清理重复校验组件,移除页面上和正则规则重复的自定义
urlValidator组件,避免两个校验逻辑冲突导致校验结果异常
可直接使用的最终配置代码
<h:inputText id="URL" value="#{geolocationBean.geolocationURL}" required="true"> <f:validateRegex pattern="^(http|https):\\/\\/(\\w+:{0,1}\\w*)?(\\S+)(:[0-9]+)?(\\/|\\/(\\w#!:.?+=&%!-\\/))?$" /> </h:inputText> <h:message style="color:red" for="URL"/>
注意:上述pattern中,
&转成&是XML解析的强制要求,双写反斜杠是适配Java正则引擎的要求,补全的^、$是实现全量输入匹配的必要锚点,调整完成后即可和原JavaScript环境下的校验逻辑保持一致。
内容的提问来源于stack exchange,提问作者DHEE MI
相关产品推荐
相关产品推荐

