正则表达式

1.正则表达式语法

  • 量词
表达式 描述 示例
X? 零次或一次匹配前面的字符或子表达式 "do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。
X* 零次或多次匹配前面的字符或子表达式 zo* 匹配"z"和"zoo"。* 等效于 {0,}。
X+ 一次或多次匹配前面的字符或子表达式 "zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。
X{n} n 是非负整数。正好匹配 n 次。 "o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。
X{n,} n 是非负整数。至少匹配 n 次 "o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效于"o+"。"o{0,}"等效于"o*"。
X{m,n} M 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次 "o{1,3}"匹配"fooooood"中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。
当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。 在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。
  • 边界匹配
表达式 描述 示例
^,$ 输入的开头和结尾(或者多行模式中的开头和结尾行) ^Java$匹配输入中的Java或Java构成的行
\A,\Z,\z 输入的开头,输入的结尾,输入的绝对结尾
\b,\B 单词边界,非单词边界 \bJava\b匹配单词Java
\R Unicode行分隔符
\G 前一个匹配的结尾
  • 序列和选择
表达式 描述 示例
XY 任何X中的字符串,后面跟随任何Y中的字符串 [1-9][0-9]*表示没有前导零的正整数
X丨Y 任何X或Y中的字符串 'z丨food' 匹配"z"或"food"。'(z丨f)ood' 匹配"zood"或"food"。
  • 群组
表达式 描述 示例
(X) 捕获X的匹配 '([^']*)'捕获的是被引用的文本
\n 第n组 ([' "]).*\1可以匹配'Fred'和"Fred",但是不能匹配"Fred'
(?<name>X) 捕获与给定名字匹配的X '(?<id>[A-Za-z0-9]+)'可以捕获名字为id的匹配
\k<name> 具有给定名字的组 \k<id>可以匹配名字为id的组
(?:X) 使用括号但是不捕获X 在(?:http丨ftp)://(.*)中,在://之后的匹配是\1
  • 字符
表达式 描述 示例
c,除.*+?{丨()[^$之外的字符 字符c ]
. 任何除行终止符之外的字符
\c,其中c不在[A-Za-z0-9]的范围内 字符c \\
\x{p} 十六进制码为p的Unicode码点 \x{1D567}
\uhhhh,\xhh,\Oo,\Ooo,\Oooo 具有给定十六进制或八进制值的码元 \uFEFF
\a,\e,\f,\n,\r,\t 响铃符(\x{7}),转义符(\x{18}),换页符(\x{8}),,换行符(\x{A}),回车符(\x{D}),制表符(\x{9}) \n
  • 字符类
表达式 描述 示例
[C1C2...] 任何由C1,C2...表示的字符 [0-9+-]
[^...] 某个字符类的补集 [^\d\s]
[...&&...] 字符类的交集 [\p{L}&&[^A-Za-z]]
\p{...}.\P{...} 某个自定义类;它的补集 \p{L}匹配一个Unicode字母,而\pL也匹配这个字母,可以忽略单个字母情况下的括号。
\d,\D 数字[0-9];它的补集,等效于 [^0-9] \d+是一个数字序列
\w,\W 单词字符[A-Za-z0-9];它的补集,与"[^A-Za-z0-9_]"等效。
\s,\S 空格([\n\r\t\f\x{8}] );它的补集([^\n\r\t\f\x{8}] )
\h,\H 水平空白字符;它的补集
\v,\V 垂直空白字符;它的补集

2.Pattern标志

标志 含义
Pattern.CASE_INSENSITIVE 匹配字符时忽略字母的大小写。
Pattern.UNICODE_CASE 当与CASE_INSENSITIVE组合使用时,用Unicode字母的大小写来匹配
Pattern.UNICODE_CHARACTER_CLASS 选择Unicode字符类代替POSIX,其中蕴含了UNICODE_CASE
Pattern.MULTILINE ^和$匹配行的开头和结尾,而不是整个输入的开头和结尾。
Pattern.UNIX_LINES 在多行模式中匹配^和$时,只有'\n'被识别成行终止符。
Pattern.DOTALL 当使用这个标志时,.符号匹配所有字符,包括行终止符。
Pattern.LITERAL 该模式将逐字的采纳,必须精确匹配,因字母大小写而造成的差异除外。
Pattern.COMMENTS 空白字符和注释(从#到行末尾)将被忽略。
Pattern.CANON_EQ 考虑Unicode字符规范的等价性。

3.Pattern类与Matcher类详解

java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:Pattern和Matcher.
Pattern:一个Pattern是一个正则表达式经编译后的表现模式。
Matcher:一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。
首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。

  • 捕获组的概念

捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:

((A)(B(C)))
(A)
(B(C))
(C)

组零始终代表整个表达式。 以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,

  • static Pattern compile(String regex):通过Pattern工厂方法产生一个Pattern对象
  • String pattern():返回正则表达式的字符串形式,
Pattern p=Pattern.compile("\\w+"); 
p.pattern();//返回 \w+ 
  • String[] split(CharSequence input):用于分隔字符串,并返回一个String[]
  • String[] split(CharSequence input, int limit):将输入字符串分割为limit大小的字符数组。如果已经发现了Limit-1个匹配的分隔符,那么返回的数组中的最后一项就包含所有剩余未分割的输入。如果limit<=0,那么整个输入都被分割。如果limit=0,那么最后的的空字符串将不会置于返回的数组中。
  • Stream<String> splitAsStream(final CharSequence input):将分割后的结构转化成流的形式
Pattern pattern = Pattern.compile("\\d+");
String[] str=pattern.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
//[我的QQ是:, 我的电话是:, 我的邮箱是:aaa@aaa.com]

String[] str=pattern.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com",2);
//[我的QQ是:, 我的电话是:0532214我的邮箱是:aaa@aaa.com]

Stream<String> stream = pattern.splitAsStream("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
//可以将pattern实例作为谓词,在Stream<String>流中进行过滤
Stream<String> result = stream.filter(pattern.asPredicate());
  • static boolean matches(String regex, CharSequence input):用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串.
Pattern.matches("\\d+","2223");//返回true 
Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到 
Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到 
  • Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern的实例方法matcher(CharSequence input)方法得到该类的实例
  • Matcher matcher(CharSequence input)
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); 
m.pattern();//返回p 也就是返回该Matcher对象是由哪个Pattern对象的创建的 

Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持.
Matcher类提供三个匹配操作方法,三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false

  • boolean matches():对整个字符串进行匹配,只有整个字符串都匹配了才返回true ;
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); 
m.matches();//返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功. 
Matcher m2=p.matcher("2223"); 
m2.matches();//返回true,因为\d+匹配到了整个字符串
  • boolean find():对字符串进行匹配,匹配到的字符串可以在任何位置.
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); 
m.find();//返回true 
Matcher m2=p.matcher("aa2223"); 
m2.find();//返回true 
Matcher m3=p.matcher("aa2223bb"); 
m3.find();//返回true 
Matcher m4=p.matcher("aabb"); 
m4.find();//返回false 
  • boolean lookingAt():对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); 
m.lookingAt();//返回true,因为\d+匹配到了前面的22 
Matcher m2=p.matcher("aa2223"); 
m2.lookingAt();//返回false,因为\d+不能匹配前面的aa 

当使用matches(),lookingAt(),find()执行匹配操作后,就可以利用以下三个方法得到更详细的信息.

  • int start():返回匹配到的子字符串在字符串中的索引位置.
  • int end():返回匹配的最后一个字符之后的偏移量
  • String group():)返回匹配到的第一个子字符串
Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("aaa2223bb"); 
m.find();//true,匹配2223 
m.start();//返回3 
m.end();//返回7,返回的是2223后的索引号 
m.group();//返回2223 
 
Matcherm2=m.matcher("2223bb"); 
m.lookingAt();   //true,匹配2223 
m.start();   //返回0,由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0 
m.end();   //返回4 
m.group();   //返回2223 
 
Matcher m3=m.matcher("2223bb"); 
m.matches();   //匹配整个字符串 
m.start();   //返回0, 
m.end();   //返回6
m.group();   //返回2223bb 

start(),end(),group()均有一个重载方法它们是start(int i),end(int i),group(int i)专用于分组操作,Mathcer类还有一个groupCount()用于返回有多少组.

  • int start(int group):
  • int end(int group):
    返回当前匹配中,给定群组的开始和结尾之后的位置。
  • String group(int group):返回匹配到的所有群组中,第几个群组.群组0是整个输入。
  • int groupCount():返回匹配到的群组数
Pattern p=Pattern.compile("([a-z]+)(\\d+)"); 
Matcher m=p.matcher("aaa2223bb"); 
m.find();   //匹配aaa2223 
m.groupCount();   //返回2,因为有2组 
m.start(1);   //返回0 返回第一组匹配到的子字符串在字符串中的索引号 
m.start(2);   //返回3 
m.end(1);   //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置. 
m.end(2);   //返回7 
m.group(1);   //返回aaa,返回第一组匹配到的子字符串 
m.group(2);   //返回2223,返回第二组匹配到的子字符串 
  • Matcher reset()
  • Matcher reset(CharSequence input):复位匹配器的状态。第二个方法将是匹配器作用于另一个不同的输入。这两个方法返回this。
  • String replaceFirst(String replacement)
  • String replaceAll(String replacement)
    返回从匹配器输入获得的通过将所有匹配或第一个匹配用替换字符串替换之后的字符串。
Pattern pattern = Pattern.compile("\\d+");        
Matcher matcher = pattern.matcher("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
matcher.replaceAll("##");//我的QQ是:##我的电话是:##我的邮箱是:aaa@aaa.com
matcher.replaceFirst("##");//我的QQ是:##我的电话是:0532214我的邮箱是:aaa@aaa.com
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容