背景
由于工作中有较多使用正则校验的地方,需要有一个统一的出口去归纳整理校验,故而在此记述
代码实现
工具函数准备
新建文件 validator.ts
interface ValidatorFn {
(rule: any, value: any, callback: Function): any;
}
class Rule {
public reg!: RegExp
public tip!: string
constructor(reg: RegExp, tip: string) {
this.reg = reg
this.tip = tip
}
public make() {
const { reg, tip } = this
const res: ValidatorFn = (rule, value, callback) => {
if (reg.test(value)) {
callback()
} else {
callback(new Error(tip))
}
}
return res
}
get value() {
return this.make()
}
}
class RuleGroup {
public rules: Rule[] = []
constructor(...rules: Rule[]) {
this.rules = rules
}
public make() {
const res: ValidatorFn[] = []
this.rules.forEach(v => {
res.push(new Rule(v.reg, v.tip).value)
})
return res
}
get value() {
return this.make()
}
}
/** 字符长度 */
const length = (min?: number, max?: number): Rule => {
min = min === undefined ? 0 : min
max = max === undefined ? Infinity : max
let tip = ''
let reg: RegExp
if (max < Infinity) {
tip = `字符长度不超过${min} - ${max}`
reg = new RegExp(`^.{${min},${max}}$`)
} else {
tip = '字符长度不少于 ' + min
reg = new RegExp(`^.{${min},}$`)
}
return new Rule(reg, tip)
}
/** 数字取值范围 */
const range = (min?: number, max?: number): ValidatorFn => {
min = min === undefined ? 0 : min
max = max === undefined ? Infinity : max
return (rule, value, callback) => {
const val = Number(value)
if (val < min) {
return callback(new Error(`取值不得小于` + min))
}
if (val > max) {
return callback(new Error(`取值不得大于` + max))
}
return callback()
}
}
编写校验代码
export class Validator {
public text = new Rule(/^[A-Za-z0-9_]*$/, '仅允许输入数字、字母、下划线').value
public range: (min: number, max?: number) => ValidatorFn = (min, max) => range(min, max)
public char36 = new RuleGroup(
new Rule(/^($|[\w-\s]+$)/, '只能输入字母、数字、空格、下划线或中划线'),
length(0, 36)
).value
}
export const validator = new Validator()
测试代码
function test(fns: ValidatorFn[] | ValidatorFn, value: number | string) {
const res: ValidatorFn[] = []
if (Array.isArray(fns)) {
res.push(...fns)
} else {
res.push(fns)
}
res.map(fn => fn(null, value, (err) => err && console.error(err, value)))
}
// 测试
test(validator.text, 'xxx')
test(validator.char36, '123456789012345678901234567890')
test(length(0, 10).value, 'dddd')
test(range(0, 10), 0)
test(validator.range(0, 10), '1')
test(new MyValidator().int, -1)