-
-
[原创]Java正则表达式笔记总结
-
2021-10-31 12:21 24152
-
Java正则表达式学习
一、前言
最近做一个web探测的项目,在项目中多处用到java
正则表达式,今天将回顾的正则表达式做一个梳理,本文属于看完廖大佬笔记后的梳理,仅为平时参考,详细大家可以查看下面相关网址。
二、学习资料
java正则表达式的学习参考以下学习资料即可:
(1)菜鸟教程:菜鸟教程的正则基础基本讲的很可以了
(2)廖雪峰的官方网站——Java篇:廖大佬的Java教程还是讲的非常清晰的
三、知识总结
1.匹配规则
(1)单个匹配规则
<1>匹配任意字符
我们使用.
匹配一个任意字符
例如:正则表达式a.c
可以匹配"abc","a&c",a_c
等,但是它并不能匹配"ac"、"a&&c"
,因为.
匹配一个字符且仅限一个字符
<2>匹配数字
我们使用\d
匹配0-9
这样的数字
例如:正则表达式00\d
可以匹配"007","008"
,它不能匹配"00A","0077"
,因为\d
仅限单个数字字符
<3>匹配常用符
我们使用\w
匹配一个字母、数字或下划线
例如:正则表达式java\w
可以匹配"javac","java9","java_"
,它不能匹配"java#","java"
,因为\w
不能匹配#
,空格等字符
<4>匹配空格字符
我们使用\s
来匹配一个空格字符,注意空格字符不但包括空格,还包括tab
字符
例如:正则表达式a\sc
可以匹配a c
,但是不能匹配"ac","abc"
<5>匹配非数字
我们使用\D
来匹配一个非数字
例如:00\D
可以匹配"00A","00#"
同理我们使用\W
来匹配非(字母、数字或下划线)
我们使用\S
来匹配非空格的字符
(2)多个字符匹配规则
<1>重复匹配
我们结合单字符匹配+多字符匹配规则就可以匹配更多的字符
情况一:数字
1 2 3 4 5 6 7 8 | ( 1 )数字 + 字母混搭 例如: "AB380" 使用修饰符 * 匹配任意个数字符,正则表达式: "AB\d*" ( 2 )数字 + 字母混搭 例如: "AB380" 使用修饰符 + 匹配至少一个字符,正则表达式: "AB\d+" ,无法匹配 "A" ,修饰符 + 可以匹配至少一个字符 ( 3 )数字 + 字符混搭 例如: "A" "A0" 使用修饰符 ? 可以匹配 0 个或一个字符,正则表达式: "A\d?" ,这里表示只匹配一个数字, "A33" 就无法匹配了 ( 4 )数字 + 字符混搭 例如: "A380" 使用修饰符 {n} 可以精确指定n个字符 正则表达式: "A\d{3}" : 可以匹配 "A389" "A\d{3,}" :可以匹配至少 3 个数字 "A\d{2,3}" :可以匹配 2 - 3 个数字 "A\d{0,3}" :可以最多匹配 3 个数字 |
情况二:电话号码
1 2 | 字符串: "010-12345678" "0755-7654321" 正则表达式: "\d{3,4}-\d{7,8}" |
2.复杂匹配规则
(1)匹配开头和结尾
我们进行多行匹配时,用^
表示开头,$
表示结束
例如:正则表达式:^A\d{3}$
可以匹配"A001"、"A380"
(2)匹配指定范围
我们用[]
可以匹配范围内的字符,例如[123456789]
或[1-9]
可以匹配1-9
情况一:电话号码(规定一个7-8数字电话号码不能从0开头)
1 2 | 字符串: "1234567" 正则表达式:[ 1 - 9 ]\d{ 6 , 7 } 理解为:范围限定 + 正则 |
情况二:任意6位十六进制数
1 2 | 字符串: "1A2b3c" 正则表达式:[ 0 - 9a - fA - F]{ 6 } |
我们在[]
中使用^
可以匹配不包含指定范围的字符
情况三:任意字符不包括数字
1 2 | 字符串: "adhkADf" 正则表示式:[^ 0 - 9 ]{ 7 } |
情况四:非负的整数和浮点数 或 非负浮点数
1 2 | [ 1 - 9 ]\d * \.?\d * 非负的整数和浮点数 0 \.\d * [ 1 - 9 ] 非负浮点数 |
(3)或规则匹配
我们用|
连接两个正则是或规则
例如我们可以使用AB|CD
来匹配AB或CD
(4)使用括号
我们用()
将子规则括起来表示
例如 我们可以使用 learn\s(java|PHP|python)
来匹配 learn java、learn PHP、learn python
3.分组匹配
前面我们已经讲了()
的好处,假如我们需要取字符串中的特定位置值,就可以用到()
了,这里我们先学习一下正则匹配式的流程
1 2 3 4 5 6 7 8 9 10 11 12 13 | / / 样例代码 String str = ""; String reg = ""; / / 设置正则匹配式 Pattern Pattern pattern = Pattern. compile = Pattern. compile (reg,Pattern.CASE_INSENSITIV); / / Pattern.CASE_INSENSITIV不区分大小 / / 开始匹配 Matcher matcher = pattern.matcher( str ) / / 判断是否找到 if (matcher.matches()){ String whole = matcher.group( 0 ); String area = matcher.group( 1 ); String tel = matcher.group( 2 ); } |
Matcher API:
索引方法:
查找方法:
替换方法:
我们经常使用indexOf()
和substring
方法来进行字符串的提取,但是这样并没有通用性,我们可以使用()
解决
1 2 3 4 5 6 7 8 9 10 11 12 | ( 1 )我们先使用()来将提取的规则分组 ( 2 )正则表达式从左到右进行匹配 ( 3 )我们将匹配的结果group提取出来即可 原理解析: ( 1 )我们预设正则表达式为:(AB (CD) (E (F) ) 我们可以看出有四个组 (AB (CD) (E (F) ) (CD) (E(F)) (F) 这里注意一下最外面的括号可有可无 ( 2 )取值 四个组匹配的结果分别存放在:m.group( 0 ) m.group( 1 ) m.group( 2 ) m.group( 3 ) 注意:我们可以使用`groupCount()`查看group长度 |
情况一:复杂字符串块提取
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static String[] RegCheck(String str ,String reg){ Pattern p = Pattern. compile (reg); Matcher m = p.matcher( str ); String[] result = new String[m.groupCount()]; if (m.matches()) { for ( int i = 0 ;i< = m.groupCount();i + + ){ result[i] = m.group(i); } return result; } else { return result; } } |
1 2 | 例如:提取 Server: nginx / 1.18 . 0 Server: * * * * Server: nginx 1.18 . 0 正则表达式: "Server:\s(\D*)(\s|\/|\*)(.*)" |
4.非贪婪匹配
我们使用正则表达式(\d+)(0*)
去匹配"1230000"
,匹配的结果是"123000" 和 空,很显然和我们想要的结果不一致,这是因为\d+
就可以匹配0
如何使得\d+
尽量少匹配,让0*
尽量多匹配,我们必须让\d+
使用非贪婪模式,即\d+?
,结果变为(\d+?)(0*)
举例:
1 2 3 4 | 字符串: "9999" 正则表达式: (\d??)( 9 * ) 结果:" " " 9999 " 因为\d?表示匹配 0 个或 1 个数字,第二个?表示非贪婪匹配,因此对于\d?来说,可以匹配一个或 0 个,非贪婪模式下就选择 0 个 |
5.搜索和替换
(1)分割字符串
我们平时使用的String.split()
就是使用的正则表达式
1 2 3 | public String[] split(String regex, int limit) regex - - 正则表达式分隔符 limit - - 分割的份数 |
例如:Set-Cookie:1234
1 2 3 4 5 6 7 | if (line.contains( "Set-Cookie" )){ String[] arr = line.split( ":" , 2 ); for (String str :arr){ String arg1 = arr[ 1 ]; String arg2 = arr[ 2 ]; } } |
(2)搜索字符串
我们平时使用substring()
来截取字符串
1 2 3 | public String substring( int beginIndex, int endIndex) beginIndex - - 起始索引(包括), 索引从 0 开始 endIndex - - 结束索引(不包括 |
我们结合正则匹配:
1 2 3 4 5 6 7 | String s = "the quick brown fox jumps over the lazy dog." ; Pattern p = Pattern. compile ( "\\wo\\w" ); Matcher m = p.matcher(s); while (m.find()) { String sub = s.substring(m.start(), m.end()); / / start第一次匹配到的位置 end匹配完成的索引值 System.out.println(sub); } |
(3)替换字符串
我们平时使用replaceAll()
来替换字符串
1 2 3 | public String replaceAll(String regex, String replacement) regex - - 匹配此字符串的正则表达式 replacement - - 用来替换每个匹配项的字符串 |
1 2 3 | String s = "The quick\t\t brown fox jumps over the lazy dog." ; String r = s.replaceAll( "\\s+" , " " ); String r = s.replaceAll( "\\s([a-z]{4})\\s" , " <b>$1</b> " ); / / 反向引用 |
四、总结
本文是回顾java正则匹配式后的笔记梳理,后续会将比较好用的正则匹配式不断补充,仅为学习使用,也供大家参考,下面给大家分享一个好用的工具:精简编程助手