正则表达式学习记录(java 版)
1.基本介绍
如果想灵活运用正则表达式,必须了解其中的各个元字符的功能,元字符从功能上大致可以分为
(1).限定符
(2).选择匹配符
(3).分组租户和反向引用
(4).特殊字符
(5)字符匹配符
(6) 定位符
java中的关键关键几个正则使用对象
Pattern (模式对象)
Matcher (匹配器对象)
例如:
package com.huilan.regexp;
import org.junit.Test;
import javax.sound.midi.Soundbank;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class regexptest {
@Test
public void regexpTest(){
String regexp = "[a-zA-Z]+";
String input = "合法和风aefs格泥马哈哈哈李四黄菲菲哈哈哈张三哈哈哈网二";
regexp01(regexp,input);
}
public void regexp01(String compile,String input){
Pattern p = Pattern.compile(compile);
Matcher matcher = p.matcher(input);
// 循环去找,找到了,就是true
// matcher.matcher() 是全部匹配的意思 要求的是目前与匹配的内容完全一直 类似于equals
while (matcher.find()){
String group = matcher.group(0);
System.out.println(group);
}
}
}
语法:
元字符(Metecharacter)-转译号 \\
\\ 符号说明:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转译符号,否者匹配不到结果,甚至报错
案例:用$去匹配 “abc$(” 会怎么样呢?
再次提示:在java中,正则表达式中,两个\\代表其他语法中的一个\
例如:一下就直接贴代码了 ,粘代码太费劲
元字符=字符匹配符
限定符:
代码 | 说明 | 举例 |
---|---|---|
* | 表示一个字符重复任意次包括0次 | (1). a* 表示希望匹配的字符串含有任意数目的字符a (2). [a-z]* 表示希望匹配到任意个小写字母 |
+ | 表示一个字符重复至少1次 | a+ 表示希望匹配的字符串中最少含有1个a字符 |
? | 1.表示一个字符出现0次或1次2.用来启用非贪婪模式3.结合:,!,=等字符用于其它功能 | 1.a? 表示希望匹配的字符串中可能含有1个a字符2.<[\s\S]+?> 去匹配得到的是,如果不加问号,则得到 3. 详见, ?:, ?=, ?! |
{ | 一般与 } 联用,表示所匹配字符的数量或数量范围 | (1). X{2} 表示匹配2个X (2). X{2,} 表示匹配2个或者更多个X (3). X{2,5} 表示匹配2-5个X |
*? | *的非贪婪写法 | (1). 见 +? (2). 另见: ?? , +? |
+? | +的非贪婪写法 | [\s\S]+?# 去匹配aaa#bbbb#时,会匹配aaa#,而[\s\S]+#则会匹配aaa#bbbb# |
?? | ?的非贪婪写法 | (1). 见 +? (2). 另见: *? , +? |
定位符:
代码 | 说明 | 举例 |
---|---|---|
^ | 1.取补集 2.表示字符串开头 | (1). [^a] 表示除了a之外的字符集,当^位于[]之中才做此用途 (2). [^\s] 表示除了空白类字符之外的所有字符集 (1). ^abc 表示希望匹配的字符串以abc开头 |
$ | 1.表示字符串结尾2.$N 表示匹配后,被正则中第N个括号所获取的内容 | (1). abc$ 表示希望匹配的字符串以abc结尾 |
代码 | 说明 | 举例 |
---|---|---|
\b | 匹配一个单词的边界 | er\b’匹配以”er”结尾的单词,’\bne’匹配以”ne”开头的单词,’\bnever\b’仅匹配单词”never” |
\B | 匹配非单词边界 | er\B’匹配任何包含”er”的单词 |
\c | 一般写法为\cx,匹配由x指明的控制字符,x的值必须为A-Z或a-z之一。否则将c视为一个原意的’c’字符 | \cM’匹配一个Control-M或回车符 |
\d | 匹配数字字符。等价于[0-9] | \d{3}’匹配3个数字 |
\D | 匹配一个非数字字符 | ‘\D{3}’匹配3个非数字字符 |
\f | 匹配一个换页符。等价于\x0c和\cL | |
\n | 匹配一个换行符。等价于\x0a和\cJ | |
\r | 匹配一个回车符。等价于\x0d和\cM | |
\s | 匹配任何空白字符,包括空格、换页、制表符等。等价于[\f\n\f\t\v] | |
\S | 匹配任何非空白字符。等价于[^v] | |
\t | 匹配一个制表符。等价于\x09和\cI | |
\v | 匹配一个垂直制表符。等价于\x0b和\cK | |
\w | 匹配包括下划线的任何单词字符。等价于[A-Xa-z0-9] | |
\W | 匹配任何非单词字符[^A-Xa-z0-9_] | |
\x | 一般写法为\xn,匹配n,其中n为16进制转义值。16进制转义值必须为确定的两个数字长。 | \x41’匹配”A”。’\x041’则等价于’ ’和”1 |
\u | 一般写法为\un,其中n是一个用四个16进制数字表示的Unicode字符 | ‘\u00A9’ 匹配版权符号© |
选择和分组:
代码 | 说明 | 举例 |
---|---|---|
一般用法为A | ||
( | 一般与 ) 联用,用来表示一个被获取的匹配 | 一般用于捕获 |
[ | 一般与 ] 联用, 用来表示一个字符的集合 | [abc] 可以匹配一个a或者一个b或者一个c [ab]+ 可以匹配多个a或者多个b或者混合,如:“ababababab” 或 “aaaaa”, “bbbbb” |
?: | 表示一个非获取匹配,它的作用是让()变成普通的范围限定符,而不将其匹配内容存储至$N中 | 'industr(?:y|ies) 可以匹industry 或者 industries |
?! | 非匹配预查,一般写法是(?!xxx),在任何不匹配xxx字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。 | (1). ‘Windows (?!95|98|NT|2000)’ 能匹配 “Windows 3.1” 中的 “Windows”,但不能匹配 “Windows 2000” 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始(2). 预查的流程,参见 ?= 的解释 |
?= | 匹配预查,一般写法是(?=xxx), 在任何匹配xxx字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。 | (1). ‘Windows (?=95|98|NT|2000)’ 能匹配 “Windows 2000” 中的 “Windows” ,但不能匹配 “Windows 3.1” 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。(2). var x=“12345”;alert(x.match(/(?=\d{2})\d{1}/g));结果弹出1,2,3,4,每次匹配只消耗1个字符,而括号内的?=\d{2}是非获取的,不消耗字符,所以匹配了1之后,是从2开始查找,而不是3。(3). 如果上方的说明不易理解,你可以把(?=)看成是一个探查敌情的侦察兵,而要被搜索的那个字符串为敌人区域,(?=xxx) 就是让?=这个侦察兵去敌人区域里找xxx, 例如上例中的?=\d{2},是要求查找2个数字,?=从头开始搜索,首先会找到12, 找到之后,我们就拿\d{1}尝试去匹配(占领)找到的这个位置,那么\d{1}就是匹配的1, 匹配结束后,相当于我们已经占领了敌人的1这个山头,?=作为侦察兵继续奔向下一个山头,23,同样,我们又拿\d{1}占领2这个山头,一直占到第4个山头,侦察兵继续往后,只有5一个数字了,不符合\d{2}这个条件(需要2个数字),侦查结束。 |
关于正则表达式的分组、捕获、反向引用
分组: 我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部门我们可以看作一个子表达式/一个分组
捕获: 把正则表达式中的 子表示/分组匹配的内容,保存到内存中以数字编号或者显示命名的组里面,方便后面引用,从左向右,以分组的左括号 为标志,第一个出现的分组的组号为1,第二分组的组号为2 以此类推.其中组0表示整个正则表达式
反向引用: 圆括号的内容被捕获到后,可以在这个括号后面被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用即可以在正则表达式内部,也可以是正则表达式外部,内部反向引用\\分组号,外部反向引用$分组号
不废话直接上图:
最后的 java 的String 类中 很多都支持正则 只要是参数带regexp的方法
例如: