在逛github的时候,发现一个很有意思的utils userhjp/datav-react

1const formatNumber = function (num) {
2  const reg = /(?=(\B)(\d{3})+$)/g
3  return num.toString().replace(reg, ',')
4}

/(?=(\B)(\d{3})+$)/g

  • (\B):这是一个捕获组,表示匹配位置的前一个字符必须不是一个单词边界(非单词字符和单词字符之间的位置)。

  • (\d{3})+:这是另一个捕获组,表示匹配连续的三个数字。

  • (?=:这是一个正向前瞻,它要求匹配位置的后面必须满足捕获组 (\B)(\d{3})+ 的模式。

  • g:这是全局标志,表示查找所有匹配项而不仅仅是第一个。

因此,这个正则表达式的作用是,在每三个数字之前插入一个逗号 ,,并确保它们之前不是单词边界。这正是您在示例中的预期输出:1,000,000,000。它将 1000000000 转换为格式化的金额字符串。

前瞻 (?=exp)

前瞻是一种正向查找,它用于查找匹配的内容后面必须满足某个条件(exp)的情况。

示例:

1// 查找后面是123的abc
2const regex = /abc(?=123)/g
3console.log('abc123'.match(regex)) // 匹配结果:['abc']
4console.log('kabc1234'.match(regex)) // 匹配结果:['abc']
5console.log('abc12'.match(regex)) // 不匹配
6console.log('abcc123'.match(regex)) // 不匹配

负前瞻 (?!exp)

负前瞻是一种负向查找,它用于查找匹配的内容后面必须不满足某个条件(exp)的情况。

示例:

1// 查找后面不是123的abc
2const regex = /abc(?!123)/g
3console.log('abc123'.match(regex)) // 不匹配
4console.log('abc1233'.match(regex)) // 不匹配
5console.log('abc12'.match(regex)) // 匹配结果:['abc']
6console.log('abcc123'.match(regex)) // 匹配结果:['abc']

后顾 (?<=exp)

后顾是一种正向查找,它用于查找匹配的内容前面必须满足某个条件(exp)的情况。

示例:

1// 查找前面是abc的123
2const regex = /(?<=abc)123/g
3console.log('abc123'.match(regex)) // 匹配结果:['123']
4console.log('kabc1234'.match(regex)) // 匹配结果:['123']
5console.log('abc12'.match(regex)) // 不匹配
6console.log('abcc123'.match(regex)) // 不匹配

负后顾 (?<!exp)

负后顾是一种负向查找,它用于查找匹配的内容前面必须不满足某个条件(exp)的情况。

示例:

1// 查找前面不是abc的123
2const regex = /(?<!abc)123/g
3console.log('abc123'.match(regex)) // 不匹配
4console.log('kabc1234'.match(regex)) // 不匹配
5console.log('ab1234'.match(regex)) // 匹配结果:['123']
6console.log('abcc123'.match(regex)) // 匹配结果:['123']

正则表达式的前瞻、负前瞻、后顾和负后顾是一些强大的技巧,用于在文本中查找特定的模式,

前瞻运算符在许多情况下都非常有用,其中一个明显的应用场景是校验密码强度。密码强度校验是确保用户创建安全密码的关键任务之一。通过使用前瞻运算符,我们可以更精确地定义密码规则,这比传统的正则表达式方式更为强大。

假设我们有以下密码规则:

  • 必须包含至少一个大写字母。
  • 必须包含至少一个小写字母。
  • 必须包含至少一个数字。
  • 必须包含至少一个特殊字符(例如:!@#$)。
  • 密码长度必须在 8 到 16 个字符之间。

若使用前瞻运算符,我们可以更精确地定义密码规则,如下所示:

1const 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 个字符之间。
  • $:这是正则表达式的结束锚点,它表示匹配必须在字符串的结尾结束。