Day03-入口管制(二)

前言

昨天在讲格式验证的时候有提到 Node.js 的 validator 跟 Go 的 govalidator 有很多好用的功能可以用,像是帮你验证 isEmail()isMobilePhone() 之类的,但万一你要的功能没有在里面呢?譬如说你想要验证的格式是台湾自来水公司的水号、或是公司自订的产品序号等等,这时就需要出动 regular expression 了,而今天就是要来说说在写 regex 时有哪些该注意的地方

Regular Expression

怕有人太久没用已经快忘记 regex 的语法XD,这边简单回顾一下:regex 是可以用来比对字串是不是符合某个 pattern 的工具,譬如说手机号码是十个数字,那我就可以写 [0-9]{10},而信箱是中间有 @ 的任意字串,那就可以写成 .+@.+,如果还是想不起来的话我找了一个 Cheat Sheet,看一看应该就会用了~

尽量不要用 +*

首先,因为任何类型的资料一定都有他的适当长度,所以应该用更确切的长度范围来做限制而不是用 +*

譬如说上面信箱 .+@.+ 的例子,你的程序应该不可能接受 a@b 这麽短的信箱吧,反之当然也不可能接受长到一万字的信箱,所以你至少应该把它改成 .{2,50}@.{5,50} 这个比较合理的范围

那为什麽要这麽讲究范围呢?因为爆长或爆短的资料通常都不会是正常的资料,比较可能是攻击者刻意造出来试探的。如果这些资料不幸进到资料库可能会导致预期外的错误

尽量不要用 .

除了不要用 +* 之外,最好也不要滥用 . 来匹配任意字元,因为绝大部分情况你想要的都不是任意字元,而是数字(\d)、英数字(\w)、或者范围更大的非空白字元(\S)

如果像上面举的例子直接用 .+@.+ 来验证信箱的话,可能就会误把 hello [email protected] 存进资料库,进而导致寄信时奇怪的 bug

没头没尾

很多人在写 regex 验证字串时会忘记把头尾的 ^$ 写进去,但因为 regex 在匹配时只要有子字串符合就可以了,因此判断出来的结果会跟原本想的不太一样

譬如说我想用 \d{5} 来检查输入是不是五位数字,是的话就有可能是台湾的邮递区号,但如果我直接写 \d{5} 的话可能会不小心接受了更长的字串,必须要写成 ^\d{5}$ 才行

const badRegex  = /\d{5}/
const goodRegex = /^\d{5}$/

badRegex.test("12345")    // true
badRegex.test("1234567")  // true(明明有七个数字却被判定为 true)

goodRegex.test("12345")   // true
goodRegex.test("1234567") // false(只允许五个数字所以判定为 false)

小结

因为各个语言都有 validator 这种 library,所以一般来说在做 input validation 不太会需要手刻 regular expression,只需要呼叫别人写好的 isEmail()isDate() 就好了

但因为还是有少数情况需要自己写 regex,所以这时候就得小心谨慎一点,才不会一个不小心就让怪怪的资料进到资料库(我就曾经这样过XD),到时候再要清理就真的很麻烦~


<<:  android studio 30天学习笔记-day 3 -介绍Service

>>:  Html表单&表单元素(DAY5)

DAY20 - 终於榨不出汁(文章) 了

计画永远赶不上变化 看了好多年的铁人赛,今年总算加入了 原本就知道可能没那麽多东西可以写,因为会的实...

Day.12 主从搭建 - 部署流程(Master Slave Replication )

了解昨天提到的主从运作流程後,今天来实际搭建主从架构~ 在前面我们起了一台VM当作Master,现在...

Day15-Nginx 限制访问来源

Nginx 直接写在 config 内 location / { allow 127.0.0.0/2...

从零开始学3D游戏开发:入门程序实作 Part.5 计算分数

这是 Roblox 从零开始系列,入门章节的第十一个单元,今天你将学会如何去计算并显示分数在画面上 ...

20.unity换场景

今天要盖出阿嬷家!让小红帽走进阿嬷家,找到阿嬷。 1.新建场景 右键 > Create >...