最近在从新学习正则表达式,把在学习过程当中所遇到的案例,还有比较难理解概念用本身的理解分析并整理总结。git
若有哪些地方不对,欢迎指正,谢谢!(๑•ᴗ•๑)github
本系列使用的JavaScript
所支持的正则表达式语法,并推荐你使用 regexr.com/ 去作相应的练习。正则表达式
假定你已经熟悉元字符
,方括号
,修饰符
,量词
及RegExp对象
。shell
若是没有,请先看一遍文档
www.w3school.com.cn/jsref/jsref…bash
本系列同步GitHub github.com/Janking/Blo…学习
$ ( ) * + . ? [ \ ^ {
ui
在文本中遇到 这几种特殊字符想转为文本,须要经过反斜杠\
转义:spa
/\$ \( \) \* \+ \. \? \[ \\ \^ \{/g
code
也许你会问到 -
减号符,}
右花括号,]
右中括号为什么不在内?首先减号符是在[]
中的,在前面没与到转义的[
左方括号时,减号符及右方括号-]
是当普通文本处理,无需转义,而花括号也如此regexp
/\{\w+}\[hello-world]/
{abc}[hello-world] hey! hey! hey!
若是须要匹配一个 yyyy-mm-dd
格式的日期,其中月份和日期都是年份的个十位
/\b\d\d(\d\d)-\1-\1\b/
反斜杠\1-9
能够获得前面分组(\d\d)
捕获到的结果,若是是10-99呢?那就\10
至\99
/\b\d\d(\d\d)-\1-\1\b/
2008-08-08
单词边界这个概念我开始比较抽象,也花了点时间去实践究竟是啥,因此在这里做为一个案例来讲说。
在单词边界匹配的位置,单词字符后面或前面不与另外一个单词字符直接相邻。 不太明白,仍是看实例吧!
"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
匹配的位置以下:
细心的你必定会发现数字的开始,小数点的左右都会有单词边界,这意味着单词边界不单单是英文字母,还包括数字。
\b
属于匹配位置的元字符,通常做占位做用,而不被捕获,同属于匹配位置的还有匹配行起始位^
和行结束位$
24小时制能够分为三段:
先匹配第一阶段: /[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]/
/[01]?[0-9]|2[0-3]/
咱们在一些场景里须要将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})+的结果为:23四、567,8后面没法补齐3位,匹配获得567
2. 匹配`\B`第2个非单词边界 `2`的右边位置,则后面(\d{3})+的结果为:34五、678,匹配获得678
3. 匹配`\B`第3个非单词边界 `3`的右边位置,则后面(\d{3})+的结果为:45六、78后面没法补齐3位,匹配获得456
4. 匹配`\B`第4个非单词边界 `4`的右边位置,则后面(\d{3})+的结果为:56七、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})+的结果为:23四、567,后面跟着8,不匹配
2. 匹配`\B`第2个非单词边界 `2`的右边位置,则后面(\d{3})+的结果为:34五、678,后面跟着非数字,位置匹配成功
3. 匹配`\B`第3个非单词边界 `3`的右边位置,则后面(\d{3})+的结果为:456,后面跟着七、8不匹配
4. 匹配`\B`第4个非单词边界 `4`的右边位置,则后面(\d{3})+的结果为:567,后面跟着8,不匹配
5. 匹配`\B`第5个非单词边界 `5`的右边位置,则后面(\d{3})+的结果为:678,后面跟着非数字,位置匹配成功
6. 最终获得获得可插入逗号的位置为2,5复制代码