正则表达式
正则表达式定义了字符串的一种规范模式,它不限制与哪种语言,通常用来处理语言规范以及文本处理。
实例:
检验Email是否正确:
1 | public static void main(String []args) |
正则语法:
- 普通字符
字母数字下划线以及没有特殊意义的标点符号都是“普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
- 简单转义字符
\n 换行符
\t 制表符
\ \ 代表\本身
^, \ $, \ (, \ ), \ { ,\ }, \ ?, \ + ,\ *, \ |, \ [, \ ] 都匹配对应的字符本身
- 标准字符集合(能够与多种字符匹配,注意区分大小写,大写是相反的意思(\ d(数字)\ D(非数字)))
\ d 任意一个数字,0-9之间的任意一个
\ w 任意一个字母或下划线,也就是A-Z,a-z,0-9,_中的任意一个;
\ s 包括空格、制表符、换行符等空白字符的其中任意一个
. 小数点可以匹配任意一个字符(除了换行符),如果要匹配包括”\n”在内的所有字符,一般要用[\s\S](任意字符匹配包含换行符)
- 自定义字符集合:
—[ ]方括号匹配方式,能够匹配方括号中的任意一个字符
[ab5@] :匹配“a”或“b”或“5”或“@”;
[^abc ]:匹配“a”,”b”,”c”以外的所有字符;
[f-k]:匹配”f”-“k”之间的任意字母;
[^ A-F0-3] :匹配“A”-“F”,”0”-“3”之外的任意字符;
正则表达式的特殊符号(除了^和-之外)包含在中括号中就失去了意义;
标准字符集合,除了小数点之外,如果被包含于中括号中,自定义字符集合包含该集合:
- [\ d .\ -+]将匹配数字,小数点、+、-;
- 量词
修饰匹配次数的特殊符号:
{n} 表达重复n次
{m,n} 表达至少重复m次,最多n次
{m,} 至少m次
? 表达式出现0\1次,相当于{0,1}
+ 表达式至少出现1次,相当于{1,}
* 表达式不出现或出现任意次,相当于{0,}
当?放在*,+之后表示尽可能匹配少的字符;
原则:
匹配次数中的贪婪模式(匹配字符越多越好,默认);
匹配次数中的非贪婪模式(匹配次数越少越好,修饰匹配次数的特殊符号后再加上?)
3.\d \d \d可以匹配3位数字==\d{3}
\d\d\d\d\d
\d==\d{3}
5.{}修饰的是直接与之相邻的符号;
\d\d{6}7个;
(\d\d){6}12个;
贪婪匹配的特点:贪婪匹配是看整个字符串是否匹配,如果不匹配它会去掉字符串的最后一个字符然后继续进行匹配,如果还是不行就继续去掉后一个字符再次尝试,知道字符串不剩下字符。
例如:
var str=’abcdabceba’
/.+b/ //匹配一个或多个结尾为b的字符
执行str.match(/.+b/)
第一次匹配abcdabceba发现不匹配,去掉a,再次进行匹配,结果正确,因而返回abcdabceb;
惰性匹配特点:惰性匹配是从左侧第一个字符向右进行匹配,先看第一个是否匹配不匹配就加上右边一个进行匹配,只要匹配成功就返回结果;
例如:
str.match(/.+?b/):第一次读入左侧第一个字符a不匹配,再加上b匹配,于是返回ab;
此外当*?出现在字符串最后时可能会出现不进行匹配的现象:
1 | import re |
运行结果为:
res1
res2 python
字符边界
- 标记匹配的不是字符而是位置,符合某种条件的位置;
^ 与字符开始的地方匹配(^i)(i开头)
$ 与字符结束的地方匹配(i$)(i结束)
\b 匹配一个单词边界
\b匹配的位置是:前面的字符与后面的字符不全是\w
java正则表达式匹配qq邮箱:
1 | String s1="[\\w\\-]+@[a-zA-Z]+(\\.[A-Za-z]{2,4}){1,2}"; |
选择符和分组
| 代表或
() 捕获组:
- 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰。
- 取匹配结果时,括号中的表达式匹配到的内容可以被单独得到。
- 每一对括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动匹配编号。捕获元素编号为0的第一个捕获根据左括号的顺序从1开始自动编号。捕获元素为0的第一个捕获是由整个正则表达式模式匹配的文本。
(?:Expression) 非捕获组,一些表达式中,不得不使用(),但又不需要保存()中子表达式匹配的内容,这时可以用非捕获组来抵消使用()带来的副作用。(节省内存,只进行匹配不进行存储,因而无法使用类似\1的方法)
- 反向引用(\nnn)
每一对()会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。
通过反向引用,可以对分组已捕获的字符串进行引用。
()捕获组:
([a-z]{2})\1:(括号内匹配到的字符重复一次):匹配类似gogo,toto此类字符;(\1匹配第一个括号)
捕获到的东西会存入内存;
预搜索(零宽断言)
- 只进行子表达式的匹配,匹配内容不计入最终结果,零宽度。(只匹配位置,不匹配结果)
- 这个位置应该符合某个条件。判断当前位置的前后字符,是否符合指定1的条件,但不匹配前后的字符;
- 正则表达式匹配过程中,如果子表达式匹配到的是字符内容,而非位置,并被保存到最终得匹配结果中,那么就认为这个子表达式是占有字符,而与之相反的,匹配到的值不保存到匹配结果中,而只是匹配位置,就认为这个子表达式是零宽度的。
(?=exp) 断言自身出现的位置的后面能匹配表达式exp;
(?<=exp) 断言自身出现的位置的前面能匹配表达式exp;
(?!exp) 断言此位置的后面不能匹配表达式exp;
(?<exp) 断言此位置的前面不能匹配表达式exp;
[a-z]+(?=\d+):a55,asd324;
mysql使用正则:
select pro_id,por_name,pro_address where por_name REGEXP ‘.000’
java使用正则:
1 | Pattern p=Pattern.compile("\\w+"); |
如果使用了find函数后可以使用group返回字符串
find函数进行多次可以将所有匹配的子串输出;
可以调用group进行分组查询输出:
1 | Pattern p=Pattern.compile("([a-z]+)([0-9]+)");//(数字字母)表示连在一起的形式 |
替换操作:
1 | Pattern p=Pattern.compile("[0-9]"); |
分割操作:
1 | String str="a232b232c23"; |