最近研究ES6, 正好ES6也有正则方面的内容, 看看有什么新特性, 顺便又把
精通正则表达式
拿出来粗看了前面几章节, 因而给本身出了几道题. 还作了一点总结.
[\b]
和\b
和\B
通常做为初学者看到这么多这些鬼都会头大了. 下面我将详细讲解一下.
[\b]
- 退格符另外其实我一直都搞不清楚[\b]
匹配一个退格(U+0008)
是什么鬼. 彷佛没有人告诉我这个退格符长什么样. 我也不知道那些各类转载各类规则的人他们本身知不知道是啥... (难道就我不知道- -)javascript
找了半天, 总算在MSDN: 正则表达式语言 - 快速参考找到了示例. 难道就是匹配\b
用的吗?, 固然很明显的区别是, 它属于字符转义
java
\b
- 一个词的边界MSDN: 匹配必须出如今\w
(字母数字)和\W
(非字母数字)字符之间的边界上。
这个就很好理解了, 会写先行断言的我固然是知道了, 他不占用任何位置, 边界通常都是单词或数字两边, 更为具体的经过MDN的正则表达式文档\b
介绍内的注意有指引, 查到ecma文档的15.10.2.6 Assertion中IsWordChar
处, 不过因为我的能力有限, 对其理解以下:git
经过这段代码(正则表达式案例分析 (一) - (3) 单词边界):es6
"I'd prefer p2p O_O".replace(/\b/g,function(){ console.log(arguments) });
输出结果:正则表达式
{ '0': '', '1': 0, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 1, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 2, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 3, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 4, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 10, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 11, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 14, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 15, '2': 'I\'d prefer p2p O_O' } { '0': '', '1': 18, '2': 'I\'d prefer p2p O_O' }
咱们看到被断掉(用|
表示)的位置分别是:ide
也就是说连续的单词
和数字
和_
组合(上文提到的ecma部分的表格也对应了这个)都是一个单位, 他的两侧就是截断. 除此以外的任何符号都会截断他们.网站
另外, 在MSDN文档中, 它被归为定位点
.ui
\B
- 一个非单词边界前面说了这么多, \B
的理解就很轻松了, 一个非单词边界. 就很少说了, 看看MSDN的例子就清楚了.spa
模式: \Bend\w*\b
code
原字符串: end sends endure lender
匹配结果: ends
和ender
其实搞正则匹配, 我我的的从精通正则表达式书中阅读后的感觉就是, 匹配必定要一个个看, 慢慢的看, 好比上面这个例子, 我看看模式先是
\B
, 而后再找原字符串, 依次步骤分析:
- 第一个
e
左边(位置)是边界不符合, 失败看下一个字符- 第二个
n
左边(位置)符合\B
, 匹配成功, 再看模式\B
后面的e
- 模式
\B
(位置)后面的e
不匹配n
, 失败再看下一个字符d
- 第三个
d
左边(位置)符合\B
, 匹配成功, 再看模式\B
后面的e
- 模式
\B
(位置)后面的e
不匹配第三个字母d
, 失败再看下一个字符(这里是个空格啦?)
- ...(此处省略, 一直到
send
单词)- (前面都不符合,当遇到了
send
), 通过一步步后移, 模式\B
(位置)走到了s
右侧, 成功! 此刻, 兴奋的将模式移到第二个e
- 好巧, 模式中的
e
匹配到s
后面的字符e
, 再回到模式下一位n
- 世界过小了, 又一次成功了, 紧接着是
d
, 看起来一一对应上了- ...(截至目前,
\Bend
部分已经和sends
中的end
配上了, 但是还没完呢)- 模式
d
后面是\w*
, 咱们回到原字符串部分send
后面是s
因此也成功了- 再看模式部分
\w*
下一位\b
, 碰到上面讲的单词边界了( •̀ ω •́ )y, 咱们看看原字符串部分sends
这里的确被截断了, 所以原字符串开始新一轮匹配- ...(反复如上步骤)
最后就得出了匹配结果的两组字符串了. 不知道我这样讲你们能不能理解, 或者说这种思路你们有没有疑问和反对之处, 若是有但愿你们留言?
本身折磨本身
匹配符合标准格式的时间. 这是内容部分:
now is 09:4 am test now isx9:4 am test now isx2:54 am test now isA09:04 amwtest now is_12:30 pm adsadadasda now is 21:59 amdsadasdwq now is 22:75 am_dsad21 now is 41:60 pm dsadsad now is 26:23 am dwadwq now is 2a:23 am dwadwq
指望结果(虽然24小时制后面存在[ap]m感受仍是不太合理.)
09:4 am 9:4 am 2:54 am 09:04 am 12:30 pm 21:59 am
看起来应该不是很复杂. 结果我写了一天没写出来. 由于我不知道怎么剔除26
. 彷佛不管怎么写, 在2
和6
之间正向断言始终都会匹配到6
. ES5倒是不支持后行断言(negative lookbehind)的, 听说ES6支持后行断言了, 才得以解决这个问题, 然而不经过后行断言来处理这个问题, 我始终没有写出来, 难道真的是实现不了?
这是一个未能完美解决的其中一种写法.
/([01]\d|(?=2(?![4-9]))2\d?|(?!2)\d):(0?(?=\d)[0-9]|[1-5][0-9])(\s*[a|p]m)/gim
这是经过后行断言的写法:
/([01]\d:|(?=2(?![4-9]))2\d?:|(?<!2)\d:)(0?(?=\d)[0-9]|[1-5][0-9])(\s*[a|p]m)/gim
再来看另外一个, 获取文件后缀名的正则写法问题:
可能有如下文件, 须要准确获取每一个文件的文件类型, 例如:
a.jpg hello world.png c.c.mp3 _do_(it)._unknow
指望:
.jpg .png .mp3 ._unknow
这个其实还算按比较简单的了. 不过在我复习正则以前硬是想不起来咋写, 稍微过了一遍再写就容易多了. 正则写法\..(?!\.).*
.
改题目来源于前几天同事发的一个javascript自验网站: ScriptOJ首页的题目.
关于题目部分, 不知道你们也有没有更好的写法, 也欢迎你们探讨纠正哦?