思维导图 JavaScript 正则表达式之字符匹配

正则表达式是匹配模式,要么匹配字符, 要么匹配位置;匹配位置实际上可以理解为匹配空字符

两种模糊匹配

    - 横向模糊匹配

        横向模糊匹配,一个正则可匹配的字符串的长度不是固定的,可以是多种情况;

        其实现方式:使用量词;

    - 纵向模糊匹配

        纵向模糊匹配,一个正则匹配的字符串,具体到某一位字符时,它可以不是确定的某个字符,可以有多种可能

        其实现方式:使用字符组

 

量词:强调的是字符出现的次数,如某个字符最少出现次数,最多出现次数

字符组:字符类,强调的是匹配字符范围

具体内容见思维导图:

 

案例分析

案例一:匹配 16 进制颜色值

/// 要求匹配:
///   #ffbbad
///   #Fc01DF
///   #FFF
///   #ffE

/// 分析:
/// 表示一个 16 进制字符,可以用字符组 [0-9a-fA-F]
/// 其中字符可以出现 3次 或 6次,这里需要用到量词和多选分支
/// 注意,使用多选分支时,需要注意顺序

let regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g
let string = '#ffbbad #Fc01df #Fc01DF #FFF #ffE'
console.log( string.match(regex) )
// => [ '#ffbbad', '#Fc01df', '#Fc01DF', '#FFF', '#ffE' ]

案例二:匹配时间

/// 以 24 小时制为例
/// 要求匹配:
///   23:59
///   02:07

/// 分析:
/// 共四位数字,第一位数字可以为 [0-2]
/// 当第一位为 2 的时候,第二位可以为 [0-3],其他情况,第二位 [0-9]
/// 第三位 [0-5], 第四位 [0-9]

let regex = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/
console.log( regex.test('23:59') )  // => true
console.log( regex.test('02:07') )  // => true

console.log( regex.test('24:00') )  // => false


/// 备注:正则中使用了 ^ 和 $ ,分别表示字符串开头和结尾 

/// 如果要求能够匹配 “7:9”,也就是前面的 0 可以省略
regex = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/
console.log( regex.test('23:59') )  // => true
console.log( regex.test('02:07') )  // => true
console.log( regex.test('7:9') )    // => true
console.log( regex.test('7:09') )   // => true

案例三:匹配日期

 

/// 以日期格式 yyyy-mm-dd 为例
/// 要求匹配:
///   2021-01-05

/// 分析:
/// 1. 年数可以是 4位数字,[0-9]{4}, 再给个额外的要求,要求配 20xx 开头的年份,则 20[0-9]{2}
/// 2. 月数,共 12 个月,分两种情况,01 ... 09 和 10 ... 12 ,可以用 (0[1-9]|1[0-2]) 
/// 3. 日数,最大 31 天,可以用 (0[1-9]|[12][0-9]|3[01])

let regex = /^20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/
console.log( regex.test('2021-01-05') )  // => true
console.log( regex.test('2099-01-01') )  // => true

console.log( regex.test('1999-01-31') )  // => false


/// 备注:正则中使用了 ^ 和 $ ,分别表示字符串开头和结尾 

案例四:匹配 windows 操作系统文件路径

/// 要求匹配:
///   D:\wakacodes\front-end\regular-expression\regular expression.pdf
///   D:\wakacodes\front-end\regular-expression\
///   D:\wakacodes\front-end
///   D:\ 

/// 分析:
/// 整体模式是:
///   盘符:\文件夹\文件夹\文件夹\文件
/// 其中匹配 'D:\',需要使用 [a-zA-Z]:\\,盘符不区分大小写,\ 需要转义
/// 文件名或文件夹名不能包含一些特殊字符,可以排除字符组 [^\\:*<>|"?\r\n]
/// 文件名或文件夹名至少包含一个字符,需要使用量词 + ,因此匹配 "文件夹\" 可以使用 [^\\:*<>|"?\r\n]+\\
/// 文件夹出现的次数,任意次,([^\\:*<>|"?\r\n]+\\)* ,括号表示其内部是一个整体
/// 路径最后一部分可以是文件夹但没有 \ ,因此需要添加 ([^\\:*<>|"?\r\n]+)?

let regex = /^[a-zA-Z]:\\([^\\:*<>|"?\r\n]+\\)*([^\\:*<>|"?\r\n]+)?$/

console.log( regex.test('D:\\wakacodes\\front-end\\regular-expression\\regular expression.pdf') )  // => true
console.log( regex.test('D:\\wakacodes\\front-end\\regular-expression\\') )  // => true
console.log( regex.test('D:\\wakacodes\\front-end') )   // => true
console.log( regex.test('D:\\') )  // => true


/// 备注:正则中使用了 ^ 和 $ ,分别表示字符串开头和结尾 

案例五:匹配 DOM 元素的 id 属性内容

/// 要求匹配:
///   <div id="container" class="main"></div>
/// 提取 id="container"

/// 分析:
///  因为要提取 id="container",最直接的想法就是 /id=".*"/  ,使用 . 通配符

let regex = /id=".*"/
let string = '<div id="container" class="main"></div>'

console.log( string.match(regex)[0] )
// => id="container" class="main"

/// 发现结果不是想要的,但接近了
/// 因为通配符 . 本身就能匹配到双引号,而量词 * 又是贪婪的,可能出现任意次数,所以会一直匹配到最后一个双引号为止
/// 那么,太贪婪了,就给它变得不贪婪,那就懒惰一下

/// 使用惰性匹配

regex = /id=".*?"/
console.log( string.match(regex)[0] )
// => id="container"

/// 但这种模式效率比较低,因为 贪婪或惰性匹配的时候,会涉及到”回溯“

/// 优化如下:
regex = /id="[^"]*"/
console.log( string.match(regex)[0] )
// => id="container"

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值