正则表达式及Java复杂文本操作
一、正则表示的基本知识
正则表达式,又称规则表达式**。**(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
-
为什么需要正则
- 文本的复杂处理
-
正则表达式的优势和用途
- 一种强大的而灵活的文本处理工具;
- 大部分编程语言、数据库、文本编辑器、开发环境都支持正则表达式;
-
正则表达式的定义
- 正如它的名字一样描述了一个规则,通过这个规则可以匹配一类字符串;
- 学习正则表达式很大程度上就是学习它的语法规则;
-
开发中使用正则表达式的流程
- 分析所要匹配的数据,写出测试用的典型数据;
- 在工具软件中进行匹配测试;
- 在程序调用通过测试的正则表达式;
-
基本语法
普通字符
- 字母、数字、汉字、下划线、以及没有特殊定义的标点符号、都是普通字符。表达式中的普通字符,在匹配一个字符串的时候、匹配与之相同的一个字符。
简单的转义字符
\n 代表换行符 \t 制表符 \\ 代表\本身 \^ ,\$ ,\. ,\{ ,\} ,\? ,\+ ,\* ,\ ,\[ ,\] 标准字符集合
- 能够与多中字符匹配表达式
- 注意区分大小写,大写是相反的意思
\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,} n,m都代表是数字
-
匹配次数中的非贪婪模式(匹配字符越少越好,修改匹配次数的特殊符号后再加上一个“?”号)
字符边界
-
本组标记匹配的不是字符而是位置,符合某种条件的位置
^ 与字符串开始的地方匹配 $ 与字符串结束的地方匹配 \b 匹配一个单词边界 -
\b匹配这样一个位置:前面的字符和后面的字符不全是\w
-
如上图 有一串字符串 lijilin312 312lijilin 正则表达式lijilin\b 匹配的如上图黄色部分
lijilin\b 在lijilin312中 左边 lijilin为\w匹配的 右边312也为\w可以匹配的 所有全是\w匹配的 所有lijilin312中的lijilin没有匹配
312lijilin 左边lijilin为\w匹配的,右边没有\w匹配的 所有不全是\w 则匹配成功lijilin
-
匹配模式
- INGORECASE忽略大小写
- 匹配时忽略大小写
- 默认情况下,正则表达式是要区分大小写的
- SINGLELINE单行模式
- 整个文件看做一个字符串,只有一个开头,一个结尾
- 使小数点“.”可以匹配包含换行符(\n)在内的任意字符
- MULTILINE多行模式
- 每行都是一个字符串,都有开头和结尾
- 在指定了MULTILINE之后,如果需要仅匹配字符串开始和结束位置,可以使用\A和\Z
选择符和分组
表达式 作用 | 分支结构 左右两边表达式之间“或”关系,匹配左边或者右边 ( ) 捕获组 (1).在被修饰匹配字数的时候,括号中的表达式可以作为整体被修饰
(2).取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到
(3) .每一对括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本(?:Expression) 非捕获组 一些表达式中,不得不使用(),但又不需要保存()中子表达式匹配的内容,这时可以用非捕获组来抵消使用()带来的副作用 测试:
- | 表示或 列如 a|b (字面意思匹配字母a或者字母b) 黄色部分为匹配内容 ab abc bc
- () 捕获组
反响引用(\nnn)
- 每一对()会分配一个编号,使用()的捕获根据左括号的顺序从1开始到自动编号
- 通过反向引用,可以对分组已捕获的字符串进行引用
预搜索(零宽断言)
-
只进行子表达式的匹配,匹配内容不计入最终的匹配结果,是零宽度
-
这个位置应该符合某个条件。判断当前位置的前后字符是否符合制定条件,但不匹配前后的字符。是对位置的匹配
-
正则表达式匹配过程中,如果子表达式匹配到的是字符内容,而非位置,并被保存到最终匹配结果中,那么就认为这个子表达式是占有字符的;如果子表达式匹配的仅仅是位置或者匹配的内容并不保存到最终的匹配结果中,那么就认为这个子表达式是零宽度的。占有字符还是零宽度,是针对匹配的内容是否保存到最终的匹配结果中而言的。
exp指的是表达式
(?=exp) 断言自身出现的位置的后面能匹配表达式exp (?<=exp) 断言自身出现的位置的前面能匹配表达式exp (?!exp) 断言此位置的后面不能匹配表达式exp (?<!exp) 断言此位置的前面不能匹配表达式exp 列如:
查找以数字结尾的 单词
查找结尾不能以数字结尾的单词
-
高级语法
-
练习
电话号码如何匹配
-
电话号码由数字和“-”构成
-
电话号码为7-8位
-
如果电话号码中包含有区号,那么区号分为三位或思位,首位是0
-
区号用“-”和其他部分分开
-
移动电话号码为11为
-
11位移动电话号码的第一位和第二位为“13”、“15”,“18”开头
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YUMaj3LN-1614306040535)(C:\Users\lijilin\AppData\Roaming\Typora\typora-user-images\image-20210225231506072.png)]
-
既能匹配电话又能匹配11为电话号码的
电邮邮箱地址验证
-
用户名有由字母、数字、中划线、下划线组成
-
@
-
网址:字母、数字组成
-
小数点:.
-
组织域名:2-4位字母组成
-
不区分大小写
国内常用的正则表达式的匹配
匹配中文字符 [\u4e00-\u9fa5] 匹配空白行 \n\s*\r 匹配HTML标记 <(\S*?)[^>]>.?</\1>|<.*?/> 匹配手尾空白字符 ^\s*|\s*$ 匹配Email地址 \w+([-+.]\w)@\w+([-.]\w).\w+([-.]\w)* 匹配网址URL [a-zA-Z]+://[^\s]* 匹配国内电话号码 0\d{2}-\d{7,9}|\d{4}-\d{7} 匹配腾讯QQ号 [1-9][0-9]{4} 匹配中国邮政编码 [1-9]\d{5}(?!\d) 匹配身份证 \d{15}|\d{18} 匹配IP地址 \d+\.\d+\.\d+\.\d+ -
二、Java复杂文本的操作
-
相关类位于:java.util.regex包下面
-
类Pattern:
- 正则表达式的编译表示形式
- Pattern p=Pattern.compile(r,int);//建立正则表达式,并启用相应模式
-
类Matcher:
- 通过解释Pattern对character sequence执行匹配操作的引擎
- Matcher m=p.matcher(str);//匹配str字符串
class Test{
public static void main(String[] args) {
//在这个字符串:abdda123344,是否符合指定的表达式:\w+
//第一步获取表达式的对象
Pattern p=Pattern.compile("\\w");
//第二步创建Matcher对象
Matcher matcher = p.matcher("abdda123344");
//第三步 具体的操作 其他方法请见API
boolean matches = matcher.matches();//尝试将整个字符序列与该正则表达式匹配
System.out.println(matches);
}
}