正则表达式

Posted by Liber Sun on January 10, 2019

正则表达式

正则表达式用于文本内容的查找和替换。

匹配单个字符

.可以用来匹配任何的单个字符,

nam.匹配包含nam*的字符串

匹配一组字符

[ ] 定义一个字符集合; 0-9、a-z、A-Z是一个区间。 ^是取非操作

abc[^0-9]匹配abc开头,并且最后一个字符不是数字的字符串。

元字符串

元字符 说明
[\b] 回退(删除)一个字符
\f 换页符
\n 换行符
\r 回车符
\t 制表符
\v 垂直制表符
\v 垂直制表符
\s 任何一个空白字符,等价于 [\f\n\r\t\v]
\S 对 \s 取非
\d 数字字符,等价于 [0-9]
\D 非数字字符,等价于 [^0-9]
\w 大小写字母,下划线和数字,等价于 [a-zA-Z0-9_]
\W 对 \w 取非

\r\n是Windows的换行符,\n是unix的换行符

\r\n\r\n是所有的空白行,因为它匹配了两个连续的换行符。

重复匹配

    • 匹配1个或多个
  • ? 匹配0个或1个
    • 匹配0个或多个

[\w.]+@\w+\.\w+匹配邮箱 [\w.]+ 代表 多个 a-z A-Z 0-9 _ . @ 代表 1个@ \w+ 代表多个 a-z A-Z 0-9 \. 代表匹配 . ,注意在[]中可以不使用转义符号

  • {n} 匹配 n 个字符
  • {m,n} 匹配 m~n 个字符
  • {m,} 至少匹配 m 个字符

懒惰和贪婪

  • 和 + 都是贪婪型元字符,会匹配尽可能多的内容。在后面加 ? 可以转换为懒惰型元字符,例如 *?、+? 和 {m, n}? 。
abcabcabc 
a.+c  // 匹配abcabcabc ,贪婪
a.+?c // 匹配abc,懒惰

位置匹配

\b 边界 ^ 字符串开头 $ 字符串尾

^\s*\/\/.*$代表 起始空白符 中间// 结尾任意 就是以//开发的注释行

java正则

捕获组和非捕获组

String text="<div style=\"color:#0000FF\">等待匹配的字符串</div>"
String reg="(<div.*?>)(?<data>.*?)(?:</div>)";
Pattern p=Pattern.compile(reg);
Matcher matcher=p.matcher(text);
matcher.find();
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group("data"));

正则表达式中每个”()”内的部分作为一个捕获组,编号为0表示整个匹配内容。 当让你也可以通过变量来获取捕获组”(?<变量>)"

至于非捕获组将”()”变为”(?:)” 即可

贪婪,勉强,独占模式

对于文本”abbbc”,正则表达式”ab{1,3}c”时 是不会发生回溯的。 但是对于文本”abc”, 在匹配完b后,他会尽可能贪婪的用文本中的”c”去继续匹配正则表达式中的”b{1,3}”,直到完全不匹配后将字符”c”吐出,用正则表达式中的”c”进行匹配,从而发生了回溯。

这里就是正则的贪婪特性,他会竭尽所能的去匹配最多的字符,直到撞了南墙。 你可以在正则之后添加? 开启懒惰模式,在该模式下,正则引擎尽可能少的重复匹配字符,匹配成功之后它会继续匹配剩余的字符串。 你也可以在正则之后添加+ 开启独占模式。同贪婪模式一样,独占模式一样会匹配最长。不过在独占模式下,正则表达式尽可能长地去匹配字符串,一旦匹配不成功就会结束匹配而不会回溯。

简单地说, 贪婪模式和占有模式相比, 贪婪模式会在只有部分匹配成功的条件下, 依次从多到少减少匹配成功部分模式的匹配数量, 将字符留给模式其他部分去匹配; 而占用模式则是占有所有能匹配成功部分, 绝不留给其他部分使用。

贪婪 懒惰 独占
X? X?? X?+
X* X*? X*+
X+ X+? X++
X{n} X{n}? X{n}+
X{n,} X{n,}? X{n,}+
X{n,m} X{n,m}? X{n,m}+

贪婪型

String text = "a<tr>aava </tr>abb ";
String reg="<.+>";
Pattern p=Pattern.compile(reg);
Matcher matcher=p.matcher(text);
while(matcher.find()){
  System.out.println(matcher.group());
  // <tr>aava </tr>
}

勉强型

String text = "a<tr>aava </tr>abb ";
String reg="<.+?>";
Pattern p=Pattern.compile(reg);
Matcher matcher=p.matcher(text);
while(matcher.find()){
  System.out.println(matcher.group());
  // <tr>
  // </tr>

独占型 它和最大匹配一样,一直匹配所有的字符,直到文本的最后,但它不由原路返回。因此会一直匹配.+,不回溯,由此没法完成正则表达式的匹配,因此不打印任何东西

String text = "a<tr>aava </tr>abb ";
String reg="<.++>";
Pattern p=Pattern.compile(reg);
Matcher matcher=p.matcher(text);
while(matcher.find()){
  System.out.println(matcher.group());
  // 不进行打印
}

String类的三个正则操作: matches(); split(); replaceAll();

java.utils.regex包中包含以下三个类:

  • Pattern 类:模式类,用于表达和陈述所要搜索模式的对象。
  • Matcher 类:匹配器类 搜索的对象。
  • PatternSyntaxException 类: 不合法的搜索模式时,抛出的异常。