正则表达式的前瞻、负前瞻、后顾和负后顾
大约 5 分钟约 1445 字
在逛github
的时候,发现一个很有意思的utils
userhjp/datav-react
const formatNumber = function (num) {
const reg = /(?=(\B)(\d{3})+$)/g;
return num.toString().replace(reg, ',');
};
/(?=(\B)(\d{3})+$)/g
(\B)
:这是一个捕获组,表示匹配位置的前一个字符必须不是一个单词边界(非单词字符和单词字符之间的位置)。(\d{3})+
:这是另一个捕获组,表示匹配连续的三个数字。(?=
:这是一个正向前瞻,它要求匹配位置的后面必须满足捕获组(\B)(\d{3})+
的模式。g:
这是全局标志,表示查找所有匹配项而不仅仅是第一个。
因此,这个正则表达式的作用是,在每三个数字之前插入一个逗号 ,,并确保它们之前不是单词边界。这正是您在示例中的预期输出:1,000,000,000
。它将 1000000000
转换为格式化的金额字符串。
前瞻 (?=exp)
前瞻是一种正向查找,它用于查找匹配的内容后面必须满足某个条件(exp)的情况。
示例:
// 查找后面是123的abc
const regex = /abc(?=123)/g;
console.log('abc123'.match(regex)); // 匹配结果:['abc']
console.log('kabc1234'.match(regex)); // 匹配结果:['abc']
console.log('abc12'.match(regex)); // 不匹配
console.log('abcc123'.match(regex)); // 不匹配
负前瞻 (?!exp)
负前瞻是一种负向查找,它用于查找匹配的内容后面必须不满足某个条件(exp)的情况。
示例:
// 查找后面不是123的abc
const regex = /abc(?!123)/g;
console.log('abc123'.match(regex)); // 不匹配
console.log('abc1233'.match(regex)); // 不匹配
console.log('abc12'.match(regex)); // 匹配结果:['abc']
console.log('abcc123'.match(regex)); // 匹配结果:['abc']
后顾 (?<=exp)
后顾是一种正向查找,它用于查找匹配的内容前面必须满足某个条件(exp)的情况。
示例:
// 查找前面是abc的123
const regex = /(?<=abc)123/g;
console.log('abc123'.match(regex)); // 匹配结果:['123']
console.log('kabc1234'.match(regex)); // 匹配结果:['123']
console.log('abc12'.match(regex)); // 不匹配
console.log('abcc123'.match(regex)); // 不匹配
负后顾 (?<!exp)
负后顾是一种负向查找,它用于查找匹配的内容前面必须不满足某个条件(exp)的情况。
示例:
// 查找前面不是abc的123
const regex = /(?<!abc)123/g;
console.log('abc123'.match(regex)); // 不匹配
console.log('kabc1234'.match(regex)); // 不匹配
console.log('ab1234'.match(regex)); // 匹配结果:['123']
console.log('abcc123'.match(regex)); // 匹配结果:['123']
正则表达式的前瞻、负前瞻、后顾和负后顾是一些强大的技巧,用于在文本中查找特定的模式,
前瞻运算符在许多情况下都非常有用,其中一个明显的应用场景是校验密码强度。密码强度校验是确保用户创建安全密码的关键任务之一。通过使用前瞻运算符,我们可以更精确地定义密码规则,这比传统的正则表达式方式更为强大。
假设我们有以下密码规则:
- 必须包含至少一个大写字母。
- 必须包含至少一个小写字母。
- 必须包含至少一个数字。
- 必须包含至少一个特殊字符(例如:!@#$)。
- 密码长度必须在 8 到 16 个字符之间。
若使用前瞻运算符,我们可以更精确地定义密码规则,如下所示:
const regex = ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#\$%^&*])[A-Za-z\d!@#\$%^&*]{8,16}$;
这个前瞻运算符的工作原理是:
^
:这是正则表达式的开始锚点,它表示匹配必须从字符串的开头开始。(?=.*[A-Z])
这是一个前瞻运算符,用于检查密码中是否至少包含一个大写字母A-Z
。 如果是,则匹配成功,否则匹配失败。 '._' 表示匹配任何字符零次或多次。所以,(?=._[A-Z])
表示匹配任何包含至少一个大写字母的字符串。(?=.*[a-z])
这是另一个前瞻运算符,用于检查密码中是否至少包含一个小写字母a-z
。 如果是,则匹配成功,否则匹配失败。 '._' 表示匹配任何字符零次或多次。所以,(?=._[a-z])
表示匹配任何包含至少一个小写字母的字符串。(?=.*\d)
这是又一个前瞻运算符,用于检查密码中是否至少包含一个数字0-9
。 如果是,则匹配成功,否则匹配失败。 '._' 表示匹配任何字符零次或多次。所以,(?=._\d)
表示匹配任何包含至少一个数字的字符串。(?=.*[!@#\$%^&*])
这是另一个前瞻运算符,用于检查密码中是否至少包含一个特殊字符!@#\$%^&*
。 如果是,则匹配成功,否则匹配失败。 '._' 表示匹配任何字符零次或多次。所以,(?=._[!@#\$%^&*])
表示匹配任何包含至少一个特殊字符的字符串。[A-Za-z\d!@#\$%^&*]{8,16}
:这是密码的实际匹配部分。它表示密码必须包含大小写字母、数字和特殊字符,且长度必须在 8 到 16 个字符之间。$
:这是正则表达式的结束锚点,它表示匹配必须在字符串的结尾结束。