在分享和总结之前,还是先来说说问题产生的情景吧:相信大家在写项目的时候,用正则验证用户的输入信息是否合法并给与相应的提示,这应该是大部分项目都会涉及到的。此坑,就是因为通过正则验证允许用户输入一些常用的中文标点符合引起的。好了,步入正题
导火索1
需要通过正则验证,来检验用户的输入是否合法,要求为:仅支持数字、字母、中文、常用标点、下划线和空格,不支持null,区分大小写,首尾不可为空格,可以为空且不超过140位。
- html 代码如下:
<div class="input-group" style="width:100%">
<span class="input-group-addon">
<i class="fa fa-info"></i>
</span>
<input maxlength="140" type="text" class="form-control" placeholder="输入重启提示" formControlName="message">
</div>
<div class="warndiv" *ngIf="test.controls.reboot_message.touched&&test.controls.message.invalid">
<i class="fa fa-times-circle text-red" title="重启提示不合法,仅支持数字、字母、中文、常用标点、下划线和空格,不支持null,区分大小写,首尾不可为空格,可以为空且不超过140位"></i>
</div>
- ts代码如下:
public test= new FormGroup({
message: new FormControl('test', [this.isTrue]),
});
isTrue(g: FormControl) {
let name = g.value;
if (name.length === 0) {
return null;
}
if (name === 'null') {
return { 'desc': true };
}
let reg_1 = /^\S/;
let reg_2 = /\S$/;
let reg_3 =/^[0-9a-zA-Z_\u4e00-\u9fa5\s\!\(\)\"\-\_\<\>\;\:\,\.\?\!\(\)\“\”\‘\’\-\——\;\:\,\。\、\?\……\《\》]+$/;
return reg_1.test(name) && reg_2.test(name) && reg_3.test(name) ? null : { 'message': true };
}
相信大家看到代码之后都会觉得完全OK吧,没错,自己也反复测试了好几遍都是可以的,没有问题。但是...........
导火索2
用ng build(有三种方式,各有不同特点,根据情况选择,我使用的是ng build --prod --aot
)编译好版本,发布给测试进行验收。
结果发现了不愿相信的问题,因为自己这边是没有问题的,测试那边所有满足正则要求的中文标点却一直报错??????
到这里基本已经交代清楚事情的始末了,但是不知道有木有同学和我一样蒙圈不知道问题原因的。还是有大牛早已看穿一切了。
原因1
通过排查之后,知道了是生产环境通过编译之后和开发环境产生了差异,所以自己查看了编译之后此处的代码为
看到这里就知道了原因了,在编译的过程中,将中文的标点符号转义成了该字符的对应Unicode码,但是又多了一个‘\’符号,所以导致验证失效。但是我们的代码又不能不写转义的‘\’,不然会报错,所以正确的方式是在代码中直接将中文的标点符号转义为对应的Unicode码。
- 修改后的代码
isLongDes(g: FormControl) {
let name = g.value;
if (name.length === 0) {
return null;
}
if (name === 'null') {
return { 'desc': true };
}
let reg_1 = /^\S/;
let reg_2 = /\S$/;
let reg_3 = /^[0-9a-zA-Z_\u4e00-\u9fa5\s\!\(\)\"\-\_\<\>\;\:\,\.\?\uff01\uff08\uff09\u201c\u201d\u2018\u2019\u2014\u2014\uff1b\uff1a\uff0c\u3002\u3001\uff1f\u2026\u2026\u300a\u300b\uff0d]+$/;
return reg_1.test(name) && reg_2.test(name) && reg_3.test(name) ? null : { 'desc': true };
}
-
修改好之后,编译对应的代码
- 测试编译版本的输入验证----------OK 没有问题了
总结
以后如果碰到类似的情况(正则表达式里面包含除了中文下的特殊字符,需要提前对应好进行相应的转义),然后一定要在编译好的版本多自测。
正则匹配 中文标点符号的整理如下:
中文符号 | 规则 | 中文符号 | 规则 |
---|---|---|---|
( | \uff08 | ) | \uff09 |
〈 | \u3008 | 〉 | \u3009 |
《 | \u300a | 》 | \u300b |
「 | \u300c | 」 | \u300d |
『 | \ufe43 | ﹄ | \ufe44 |
〔 | \u3014 | 〕 | \u3015 |
… | \u2026 | — | \u2014 |
~ | \uff5e | ﹏ | \ufe4f |
¥ | \uffe5 | 、 | \u3001 |
【 | \u3010 | 】 | \u3011 |
, | \uff0c | 。 | \u3002 |
? | \uff1f | ! | \uff01 |
: | \uff1a | ; | \uff1b |
“ | \u201c | ” | \u201d |
‘ | \u2018 | ’ | \u2019 |
* | \u002a | @ | \u0040 |
如没有找到的,可以在站长工具-站长之家网站直接转化