正则表达式位置匹配攻略【转】
正则表达式是匹配模式,要么匹配字符,要么匹配位置。请记住这句话。
然而大部分人学习正则时,对于匹配位置的重视程度没有那么高。
本文讲讲正则匹配位置的总总。
内容包括:
1. 什么是位置?
2. 如何匹配位置?
3. 位置的特性
4. 几个应用实例分析
位置是相邻字符之间的位置。比如,下图中箭头所指的地方:
在ES5中,共有6个锚字符:
2.1 ^和$
^(脱字符)匹配开头,在多行匹配中匹配行开头。
$(美元符号)匹配结尾,在多行匹配中匹配行结尾。
比如我们把字符串的开头和结尾用"#"替换(位置可以替换成字符的!):
多行匹配模式时,二者是行的概念,这个需要我们的注意:
2.2 \b和\B
\b是单词边界,具体就是\w和\W之间的位置,也包括\w和^之间的位置,也包括\w和$之间的位置。
比如一个文件名是"[JS] Lesson_01.mp4"中的\b,如下:
为什么是这样呢?这需要仔细看看。
首先,我们知道,\w是字符组[0-9a-zA-Z_]的简写形式,即\w是字母数字或者下划线的中任何一个字符。而\W是排除字符组[^0-9a-zA-Z_]的简写形式,即\W是\w以外的任何一个字符。
此时我们可以看看"[#JS#] #Lesson_01#.#mp4#"中的每一个"#",是怎么来的。
第一个"#",两边是"["与"J",是\W和\w之间的位置。
第二个"#",两边是"S"与"]",也就是\w和\W之间的位置。
第三个"#",两边是空格与"L",也就是\W和\w之间的位置。
第四个"#",两边是"1"与".",也就是\w和\W之间的位置。
第五个"#",两边是"."与"m",也就是\W和\w之间的位置。
第六个"#",其对应的位置是结尾,但其前面的字符"4"是\w,即\w和$之间的位置。
知道了\b的概念后,那么\B也就相对好理解了。
\B就是\b的反面的意思,非单词边界。例如在字符串中所有位置中,扣掉\b,剩下的都是\B的。
具体说来就是\w与\w、\W与\W、^与\W,\W与$之间的位置。
比如上面的例子,把所有\B替换成"#":
2.3 (?=p)和(?!p)
(?=p),其中p是一个子模式,即p前面的位置。
比如(?=l),表示'l'字符前面的位置,例如:
而(?!p)就是(?=p)的反面意思,比如:
二者的学名分别是positive lookahead和negative lookahead。
中文翻译分别是正向先行断言和负向先行断言。
ES6中,还支持positive lookbehind和negative lookbehind。
具体是(?<=p)和(?<!p)。
也有书上把这四个东西,翻译成环视,即看看左边或看看右边。
但一般书上,没有很好强调这四者是个位置。
比如(?=p),一般都理解成:要求接下来的字符与p匹配,但不能包括p的那些字符。
而在本人看来(?=p)就与^一样好理解,就是p前面的那个位置。
对于位置的理解,我们可以理解成空字符""。
比如"hello"字符串等价于如下的形式:
也等价于:
因此,把/ hello$/写成/ ^hello$$$/,是没有任何问题的:
甚至可以写成更复杂的:
也就是说字符之间的位置,可以写成多个。
把位置理解空字符,是对位置非常有效的理解方式。
4.1 不匹配任何东西的正则
让你写个正则不匹配任何东西
easy,/.^/
因为此正则要求只有一个字符,但该字符后面是开头。
4.2 数字的千位分隔符表示法
比如把"12345678",变成"12,345,678"。
可见是需要把相应的位置替换成","。
思路是什么呢?
4.2.1 弄出最后一个逗号
使用(?=\d{3}$)就可以做到:
4.2.2 弄出所有的逗号
因为逗号出现的位置,要求后面3个数字一组,也就是\d{3}至少出现一次。
此时可以使用量词+:
4.2.3 匹配其余案例
写完正则后,要多验证几个案例,此时我们会发现问题:
因为上面的正则,仅仅表示把从结尾向前数,一但是3的倍数,就把其前面的位置替换成逗号。因此才会出现这个问题。
怎么解决呢?我们要求匹配的到这个位置不能是开头。
我们知道匹配开头可以使用^,但要求这个位置不是开头怎么办?
easy,(?!^),你想到了吗?测试如下:
4.2.4 支持其他形式
如果要把"12345678 123456789"替换成"12,345,678 123,456,789"。
此时我们需要修改正则,把里面的开头^和结尾$,替换成\b:
其中(?!\b)怎么理解呢?
要求当前是一个位置,但不是\b前面的位置,其实(?!\b)说的就是\B。
因此最终正则变成了:/\B(?=(\d{3})+\b)/g
4.3 验证密码问题
密码长度6-12位,由数字、小写字符和大写字母组成,但必须至少包括2种字符。
此题,如果写成多个正则来判断,比较容易。但要写成一个正则就比较困难。
那么,我们就来挑战一下。看看我们对位置的理解是否深刻。
4.3.1 简化
不考虑“但必须至少包括2种字符”这一条件。我们可以容易写出:
4.3.2 判断是否包含有某一种字符
假设,要求的必须包含数字,怎么办?此时我们可以使用(?=.*[0-9])来做。
因此正则变成:
4.3.3 同时包含具体两种字符
比如同时包含数字和小写字母,可以用(?=. [0-9])(?=. [a-z])来做。
因此正则变成:
4.3.4 解答
我们可以把原题变成下列几种情况之一:
1.同时包含数字和小写字母
2.同时包含数字和大写字母
3.同时包含小写字母和大写字母
4.同时包含数字、小写字母和大写字母
以上的4种情况是或的关系(实际上,可以不用第4条)。
最终答案是:
4.3.5 解惑
上面的正则看起来比较复杂,只要理解了第二步,其余就全部理解了。
/(?=.*[0-9])^[0-9A-Za-z]{6,12}$/
对于这个正则,我们只需要弄明白(?=.*[0-9])^即可。
分开来看就是(?=.*[0-9])和^。
表示开头前面还有个位置(当然也是开头,即同一个位置,想想之前的空字符类比)。
(?=. [0-9])表示该位置后面的字符匹配. [0-9],即,有任何多个任意字符,后面再跟个数字。
翻译成大白话,就是接下来的字符,必须包含个数字。
4.3.6 另外一种解法
“至少包含两种字符”的意思就是说,不能全部都是数字,也不能全部都是小写字母,也不能全部都是大写字母。
那么要求“不能全部都是数字”,怎么做呢?(?!p)出马!
对应的正则是:
三种“都不能”呢?
最终答案是:
位置匹配相关的案例,挺多的,不一而足。
感谢你看到这里,本文也要结束了。
如果有更好的例子,也可以帮我补充补充。
最后,我们该想到,陆游诗人对前端做的最大贡献是:
纸上得来终觉浅,绝知此事要躬行。
本文完。
系列总目录传送门
正则表达式位置匹配攻略【转】
第二个"#",两边是"S"与"]",也就是\\w和\\W之间的位置。第三个"#",两边是空格与"L",也就是\\W和\\w之间的位置。第四个"#",两边是"1"与".",也就是\\w和\\W之间的位置。第五个"#",两边是"."与"m",也就是\\W和\\w之间的位置。第六个"#",其对应的位置是结尾,但其前面的字...
正则表达式位置匹配攻略
在ES5中,我们有6个锚字符:^, $, \\b, \\B, (?=p), (?!p)。2.1 ^和 ^匹配字符串的开头,而$在多行匹配中则匹配行的结尾。2.2 \\b和\\B \\b是单词边界,即\\w和\\W之间的位置。比如文件名中的“Lesson_01”中的\\b就是单词边界。2.3 (?=p)和(?!p)(?=p)表示p前面的位置,而...
怎么让正则表达式从字符串的右边开始匹配
1、使用反向字符类:反向字符类用“^”符号在方括号内表示,可以匹配不在指定字符类内的任意字符。如果在正则表达式的开头使用了一个反向字符类,并且将所有可能的字符都包含进去,匹配的位置就会从字符串的右边开始向左匹配。2、使用贪婪模式:正则表达式默认是贪婪的,会尽可能多地匹配字符串。如果希望从...
如何用正则表达式匹配指定位置的数字?
匹配正则:(?<=[0-9a-zA-Z]{14})(\\d{4})如果只匹配15位到第18位的数字的话不要使用全局匹配,使用全局匹配会返回多个子表达示结果
正则表达式匹配字符串指定位置问题
是不是就是这四位位数字呢?或是说这四位数字是在这个字符串的最前面的四位字符串,要是这样可以这样写正则表达式:("\/d{4}"),当然不同的语言还有一点不太一样,要是java的话就是这样写的:Pattern.compile("\\\\d{4}");希望可以帮助到楼主,不懂可以追问 ...
正则表达式数字匹配规则整理
这篇文章详细介绍了正则表达式中各种数字匹配的规则,包括:匹配精确数字:直接表示特定的数字,如"2"。匹配n位数字:使用{n}表示n个数字,如"\\\\d{n}"匹配n位的整数。匹配至少n位:用{n,}表示至少n位,如"\\\\d{n,}"。匹配m到n位:{m,n}表示m到n位的范围,如"\\\\d{m,n}"。区分开头:...
正则表达式如何匹配空值?
正则表达式匹配空值方式如下:\\b 匹配单词开头或结尾位置 ^ 匹配字符串开端位置 匹配字符串结尾位置 \\s 匹配一切空白字符 \\n 匹配换行 正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
正则表达式匹配规则
首先对字符串位置做标记,方便我们观察 同样的,我们对正则表达式 \/bc\/g 进行拆解为 b 与 c 两部分 匹配的过程如下:①当正则匹配不成功的时候,就会尝试进行回溯 ②回溯成功与否取决于是否有可回溯的位置 ③若没有会回溯位置,则整个正则表达式匹配失败,控制权交还给表达式的起始位置 ④正则规则中使用...
正则表达式,如何匹配除了空格之外的所有字符?
\\S+ 则表示一次或多次出现的除了空格之外的字符。这看起来很简单,但是一些自以为是的半调子却常常误导他人。正确的用法是根据实际需求选择 \\S 或 \\S+,例如,如果你需要匹配一次或多次非空格字符,就可以使用 \\S+。而如果只需要匹配一次非空格字符,则使用 \\S 即可。正确理解和运用这些正则表达式...
正则表达式字符匹配
正则表达式是匹配模式,要么匹配字符,要么匹配位置 本文所用图示化工具: Regulex 横向模糊指的是,一个正则可匹配的字符串的长度不是固定的,可以是多种情况的 其实现的方式是使用量词。譬如 {m,n} ,表示连续出现最少 m 次,最多 n 次 纵向模糊指的是,一个正则匹配的字符串,具体到...