正则表达式案例分析 (一)

前言

最近在重新学习正则表达式,把在学习过程中所遇到的案例,还有比较难理解概念用自己的理解分析并整理总结。

如有哪些地方不对,欢迎指正,谢谢!(๑•ᴗ•๑)

本系列使用的JavaScript所支持的正则表达式语法,并推荐你使用 regexr.com/ 去做相应的练习。

假定你已经熟悉元字符方括号修饰符,量词RegExp对象

如果没有,请先看一遍文档
www.w3school.com.cn/jsref/jsref…

本系列同步GitHub github.com/Janking/Blo…

案例分析

(1) 需要转义的特殊字符

$ ( ) * + . ? [ \ ^ {

在文本中遇到 这几种特殊字符想转为文本,需要通过反斜杠\转义:

/\$ \( \) \* \+ \. \? \[ \\ \^ \{/g

也许你会问到 -减号符,}右花括号,]右中括号为何不在内?首先减号符是在[]中的,在前面没与到转义的[左方括号时,减号符及右方括号-]是当普通文本处理,无需转义,而花括号也如此

  • Try it: regexr.com/
  • Regexp : /\{\w+}\[hello-world]/
  • Text : {abc}[hello-world] hey! hey! hey!
(2) 再次匹配先前匹配的文本

如果需要匹配一个 yyyy-mm-dd 格式的日期,其中月份和日期都是年份的个十位

/\b\d\d(\d\d)-\1-\1\b/

反斜杠\1-9可以得到前面分组(\d\d)捕获到的结果,如果是10-99呢?那就\10\99

  • Try it: regexr.com/
  • Regexp : /\b\d\d(\d\d)-\1-\1\b/
  • Text : 2008-08-08
(3) 单词边界

单词边界这个概念我开始比较抽象,也花了点时间去实践到底是啥,所以在这里作为一个案例来说说。

在单词边界匹配的位置,单词字符后面或前面不与另一个单词字符直接相邻。 不太明白,还是看实例吧!

"That dang-tootin' #!@#$ varmint's cost me $199.95!".replace(/\b/g,function(){
 console.log(arguments)
});复制代码
//output
["", 0, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 4, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 5, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 9, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 10, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 16, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 24, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 31, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 32, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 33, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 34, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 38, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 39, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 41, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 43, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 46, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 47, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 49, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]复制代码

通过控制台输出,我们可以发现\b匹配的位置如下:

https://user-gold-cdn.xitu.io/2017/7/11/3b6b20924441295026cd34c12e2a210a

细心的你一定会发现数字的开始,小数点的左右都会有单词边界,这意味着单词边界不仅仅是英文字母,还包括数字。

\b属于匹配位置的元字符,一般作占位作用,而不被捕获,同属于匹配位置的还有匹配行起始位^和行结束位$

(4) 处理24小时制时间

24小时制可以分为三段:

  1. 00 - 09
  2. 10 - 19
  3. 20 - 23

先匹配第一阶段: /[0][0-9]/

再接着匹配第二阶段:/[01][0-9]/

第三阶段以此类推?/[012][0-9]/

明显不合适,因为不可能出现大于23以上的数字,那么只能开分支了 /[01][0-9]|2[0-3]/

也许你会说,00-09如果要匹配“没有补零”的情况呢?(即:0,1,2,3,4,5...)

我们可以借助一下量词?匹配 /[01]?[0-9]|2[0-3]/

(5) 千分位

我们在一些场景里需要将7654321输出成7,654,321这样的格式,这就是千分位,用正则表达式去处理的话,关键是获取位置,那么首先想到的就是要利用非单词边界\B,下面这条正则是能成功取得千分位的位置的:

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

先将这个正则分解成三部分:

1 )、 /\B(?=\d)/ 这是\B是为了防止出现,123起始位置被匹配的问题,(?=\d)是非单词边界后紧跟数字

2 )、 尝试一下8位数的数字: '12345678' 在 /\B(?=(\d{3})+)/匹配得到什么结果呢?

// input
'12345678'.replace(/\B(?=(\d{3})+)/g,function(){console.log(arguments);return '|'})复制代码
// output
["", "567", 1, "12345678"]
["", "678", 2, "12345678"]
["", "456", 3, "12345678"]
["", "567", 4, "12345678"]
["", "678", 5, "12345678"]

"1|2|3|4|5|678"复制代码

首先符合非单词边界\B的有1,2,3,4,5,6,7的右边位置,而后面也同样紧跟数字2,3,4,5,6,7

其次符合\d{3}的有234,345,456,567,678,但后面跟个加号+结果就不一样了

那为什么会得到567,678,456,567,678,这样奇怪的匹配?原理如下:

1. 匹配`\B`第1个非单词边界 `1`的右边位置,则后面(\d{3})+的结果为:234、567,8后面无法补齐3位,匹配得到567
2. 匹配`\B`第2个非单词边界 `2`的右边位置,则后面(\d{3})+的结果为:345、678,匹配得到678
3. 匹配`\B`第3个非单词边界 `3`的右边位置,则后面(\d{3})+的结果为:456、78后面无法补齐3位,匹配得到456
4. 匹配`\B`第4个非单词边界 `4`的右边位置,则后面(\d{3})+的结果为:567、8后面无法补齐3位,匹配得到567
5. 匹配`\B`第5个非单词边界 `5`的右边位置,则后面(\d{3})+的结果为:678
6. 匹配`\B`第6个非单词边界 `6`的右边位置,但78无法补齐3位,
7. 同6
8. 最终小括号分组匹配得到的分别是:567,678,456,567,678复制代码

3 )、最后 (?!\d) 是前面匹配成功后跟的非数字,那连起来就是:

1. 匹配`\B`第1个非单词边界 `1`的右边位置,则后面(\d{3})+的结果为:234、567,后面跟着8,不匹配
2. 匹配`\B`第2个非单词边界 `2`的右边位置,则后面(\d{3})+的结果为:345、678,后面跟着非数字,位置匹配成功
3. 匹配`\B`第3个非单词边界 `3`的右边位置,则后面(\d{3})+的结果为:456,后面跟着7、8不匹配
4. 匹配`\B`第4个非单词边界 `4`的右边位置,则后面(\d{3})+的结果为:567,后面跟着8,不匹配
5. 匹配`\B`第5个非单词边界 `5`的右边位置,则后面(\d{3})+的结果为:678,后面跟着非数字,位置匹配成功
6. 最终得到得到可插入逗号的位置为2,5复制代码

参考文献:

  • 《精通正则表达式》
  • 《正则表达式经典实例》

转载于:https://juejin.im/post/5964e1ca51882568d2248b61

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
正则表达式是一种用来描述和匹配字符串模式的工具。通过了解和掌握正则表达式,可以更高效地处理和操作文本数据。 精通正则表达式PDF是一本详细介绍和讲解正则表达式的电子书,其内容涵盖了正则表达式的基础知识和高级应用技巧。 首先,这本PDF将从基础知识开始介绍正则表达式的语法和常用的元字符,包括字符类、限定符、分组和捕获等。通过学习这些基础知识,读者可以了解如何构建简单的正则表达式来匹配指定的字符串模式。 其次,这本PDF还介绍了正则表达式的高级用法,例如反向引用、零宽断言和嵌入代码等。这些高级技巧可以帮助读者更准确地定位和捕获特定的字符串内容。 除了语法和用法介绍,这本PDF还提供了大量的实例和案例分析,通过具体的示例来演示如何使用正则表达式解决常见的文本处理问题。这些实例覆盖了从简单的字符串匹配到更复杂的文本提取和替换等不同应用场景。 此外,这本PDF还介绍了一些常用的正则表达式工具和库,如Python的re模块和JavaScript的RegExp对象等。这些工具和库提供了更便捷和高效的正则表达式操作方式,读者可以根据自己的需要选择和使用。 总结来说,精通正则表达式PDF是一本系统和全面介绍正则表达式的电子书,通过学习这本书,读者可以掌握正则表达式的基础知识和高级应用技巧,并且能够运用正则表达式解决实际的文本处理问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值