技术问询:如何将单行正则表达式重构为多行?
如何将单行正则表达式重构为多行形式?
先看你提供的原代码:
export const emailStrictAccounting = value => // eslint-disable-next-line vue/max-len,no-control-regex value && !/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ig.test(value) ? 'error' : undefined;
要把这种超长单行正则改成多行,有两种实用方法:
方法一:用RegExp构造函数拆分字符串拼接
把正则的各个逻辑段拆成多个字符串,用+连接换行书写,需要注意字符串里的反斜杠要双重转义(因为字符串本身会解析一层反斜杠),同时保留原有的ig修饰符。
重构后的代码:
export const emailStrictAccounting = value => { // eslint-disable-next-line no-control-regex const emailRegex = new RegExp( '(?:[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*|' + '"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|' + '\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*")@' + '(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|' + '\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}' + '(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:' + '(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|' + '\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])', 'ig' ); return value && !emailRegex.test(value) ? 'error' : undefined; };
方法二:使用模板字符串和x修饰符(ES2018+)
ES2018及之后支持x修饰符,它会忽略正则模式中的空白字符(转义的空白或字符类里的除外),还允许添加注释,能让正则结构更清晰。
重构后的代码:
export const emailStrictAccounting = value => { // eslint-disable-next-line no-control-regex const emailRegex = new RegExp(` (?: # 匹配常规邮箱用户名 [a-z0-9!#$%&'*+/=?^_\`{|}~-]+ (?:\\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)* | # 匹配带引号的特殊用户名 "(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*" )@ (?: # 匹配域名形式的邮箱后缀 (?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+ [a-z0-9](?:[a-z0-9-]*[a-z0-9])? | # 匹配IP形式的邮箱后缀 \\[(?: (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\. ){3} (?: 25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]? | [a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+ )\\] ) `, 'igx'); // 新增x修饰符,忽略空白并支持注释 return value && !emailRegex.test(value) ? 'error' : undefined; };
两种方法对比
- 方法一兼容性更好,能适配所有支持ES5及以上的环境;
- 方法二可读性更强,还能添加注释说明正则各段的作用,适合现代项目。
内容的提问来源于stack exchange,提问作者user10717010
相关产品推荐
相关产品推荐

