越努力,越幸运,做个ccode~

0%

关于正则的灵活运用

1 替换字符串中最后出现的字符串

(?!exp) 零宽度负预测先行断言

'abcxxyyabczioewf'.replace(/abc(?!\w*abc)/,'ABC')   // "abcxxyyABCzioewf"
'abcabcxxxabcbxx'.replace(/abc(?!\w*abc)/,'ABC')    //  "abcabcxxxABCbxx"

2 将数字转为金额表示

3 计算字符串中重复出现的字符的个数

// 'abc' = > 0
// 'aabbb' => 2   // 因为 a和b重复出现了,是两个字符
function duplicateCount(text){
  return (text.toLowerCase().split('').sort().join('').match(/(.)\1+/g) || []).length
} 

4 交换字符串中的两个单词 (mdn)

使用$1 和 $2 代替替换文本

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1"); // Smith, John

5 修改日期格式

var reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
'2020-06-20'.replace(reg,'$<year>/$<month>/$<day>')      // "2020/06/20"

var reg = /(\d{4})-(\d{2})-(\d{2})/
'2020-06-20'.replace(reg,'$1/$2/$3')       // "2020/06/20" 

6 将驼峰命名法改为 “-“ 命名

'borderTop'.replace(/[A-Z]/g,value=>'-'+value.toLowerCase())   // border-top

7 将华氏温度转为摄氏温度 (mdn)

8 leetCode 8 字符串转整数 (规则与parseInt相同)

即用正则实现parseInt

var myAtoi = function(str) {
  var INT_MAX = 2**31-1
  var INT_MIN = (-2)**31
  var num = str.match(/^\s*([\+\-]?\d+)/)
  return Math.max(Math.min(num ? num[1]: 0,INT_MAX),INT_MIN)
}

9 leetCode 16.18 模式匹配

你有两个字符串,即pattern和value。 pattern字符串由字母”a”和”b”组成,用于描述字符串中的模式。
例如,字符串”catcatgocatgo”匹配模式”aabab”(其中”cat”是”a”,”go”是”b”),
该字符串也匹配像”a”、”ab”和”b”这样的模式。但需注意”a”和”b”不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。

输入: pattern = “abba”, value = “dogcatcatdog”
输出: true

// 思路 命名分组 反向引用
var patternMatching = function(pattern, value) {
  if(pattern === '') return value === ''
  let reg = pattern.replace('a','(?<a>\\w*)').replace('b','(?<b>\\w*)')
  reg = reg.replace(/(?<!\<)a/g,'\\k<a>').replace(/(?<!\<)b/g,'\\k<b>')
  let match = new RegExp('^'+reg+'$').exec(value)
  return !!match && match[1] !== match[2]
}

10 计算字符串中重复出现的字符的个数

‘abc’ = > 0 // 没有重复的字符
‘aabbb’ => 2 // 因为 a和b重复出现了,是两个字符

// match 使用g标志,则将返回与完整正则表达式匹配的所有结果
function duplicateCount(text){
  return (text.toLowerCase().split('').sort().join('').match(/(.)\1+/g) || []).length
}

11 密码正则 6-20位 字母与数字的组合

要求字母与数字的组合 不能全为数字 也不能全为字母

// 1 排除法
/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9a-zA-Z]{6,20}$/
// 2 包含法
/^(?=.*[0-9])(?=.*[a-zA-Z])(.{6,20})$/      // 最后的一组括号可以不要

如果要求还要包含大写字母

/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(.{6,20})$/

我的问题
为什么 (?=exp)可以判断 而 (?<=exp) 不可以

原来是因为 ?<=不能匹配任意长度的东西