正则表达式

255 阅读7分钟

正则表达式语法

元字符

转义符号 \\

Java中两个\\代表其他语言中的一个\

需要用到转义符号的字符有:. * + () / \ ? [] ^ {}

字符匹配符

符号符号示例解释
[ ]可接收的字符列表[efgh]e、f、g、h中的任意1个字符
[^]不接收的字符列表[^abc]除a、b、c之外的任意1个字符,包括数字和特殊符号。
-连字符A-Z任意单个大写字母
.匹配除\n以外的任何字符a..b以a开头,b结尾,中间包括2个任意字符的长度为4的字符串
\\d匹配单个数字字符,相当于[0-9]\\d{3}(\\d)?包含3个或4个数字的字符串
\\D匹配单个非数字字符,相当于[^0-9]\\D(\d)*以单个非数字字符开头,后接任意个数字字符串
\\w匹配单个数字,大小写字母字符和下划线,相当于[0-9a-zA-Z]\\d{3}\\w{4}以3个数字字符开头的长度为7的数字字母字符串
\\W匹配单个非数字,大小写字母字符或下划线,相当于[^0-9a-zA-Z]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串
\\s匹配任何非空白字符(空格,制表符等)
\\S匹配任何非空白字符,和\\s刚好相反

应用实例

  • Java正则表达式默认是区分字母大小写的
    • (?i)abc表示abc都不区分大小写
    • a(?I)bc表示bc不区分大小写
    • a((?i)b)c表示只有b不区分大小写
    • Pattren pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE)表示都不区分大小写

选择匹配符

在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个。

符号符号示例解释
|匹配 |之前或之后的表达式ab|cdab或者cd

限定符

用于指定其前面的字符和组合项连续出现多少次

符号含义示例说明匹配输入
*指定字符重复0次或n次(abc)*仅包含任意个abc的字符串abc、abcabc
+指定字符重复1次或n次m+(abc)*以至少1个m开头,后接任意个abc的字符串m、mabc、mabcabc、
指定字符重复0次或者1次m+abc?以至少1个m开头,后接ab或者abc的字符串mab、mabc、mmmab、mmabc
{n}只能输入n个字符[abcd]{3}由abcd中字母组成的任意长度为3的字符串abc、dbc、adc
{n,}指定至少n个匹配[abcd]{3,}由abcd中字母组成的任意长度不小于3的字符串aab、aaadbc
{n, m}指定至少n个但不多于m个匹配[abcd]{3, 5}由abcd中字母组成的任意长度不小于3,不大于5的字符串abc、abcd、aaaa-
更改其紧跟的限定符为非贪婪匹配o+?在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。
  • 贪婪匹配

    Java默认贪婪匹配,即尽可能匹配多的。a{3, 4}会首先去匹配4个a。

定位符

规定要匹配的字符串出现的位置,比如在字符串的开始还是结束的位置。

符号含义示例说明匹配输入
^指定起始字符^[0-9]+[a-z]*以至少1个数字开头,后接任意个小写字母的字符串123、6aa
$指定结束字符^[0-9]\\-[a-z]+$以1个数字开头后接连字符“-”,并以至少1个小写字母结尾的字符串1-a
\\b匹配目标字符串的边界tan\\b这里说的字符串的边界指的是字串间有空格,或者是目标字符串的结束位置tangtan tangrentan
\\B匹配目标字符串的非边界tan\\B和\\b的含义相反tangtan tangrentan

分组

捕获分组

常用分组构造形式说明
(pattern)非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号。
(?<name>pattern)命名捕获。将匹配的子字符串捕获到一个组名或编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号代替尖括号,例如(?'name')
String regStr = "(?<g1\\d\\d)(?<g2>\\d\\d)";

Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattren.matcher(content);

while(matcher.find()){
    System.out.println("找到=" + matcher.group(0));
    System.out.println("第一个分组内容=" + matcher.group(1));
    System.out.println("第一个分组内容[通过组名]=" + matcher.group("g1"));
     System.out.println("第二个分组内容=" + matcher.group(2));
    System.out.println("第二个分组内容[通过组名]=" + matcher.group("g2"));
}

非捕获分组

非捕获分组不能使用matcher.group(1) matcher.group(2)等分组捕获。matcher.group(0)可以。

常用分组构造形式说明
(?:pattern)匹配pattren但不捕获匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用“or“字符(|)组合模式部件的情况很有用。例如,'industr(?:y|ies)'是比industry|industries更经济的表达式。
(?=pattern) 它是一个非捕获匹配。例如,Windows (?=95|98|NT|2000)匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。
(?!pattern)该表达式匹配不处于匹配pattren的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如,'Windows (?!95|98|NT|2000)'匹配"Windows 3.1"中的"Windows",但不匹配"Windows 2000"中的"Windows"。

反向引用

圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用**\\分组号**,外部反向引用**$分组号**。

  • 匹配两个连续的相同数字:(\\d)\\1
  • 匹配五个连续的相同数字:(\\d)\\1{4}
  • 匹配个位与千位相同,十位与百位相同的数字:(\\d)(\\d)\\2\\1
  • 去掉重复的字:Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");

应用实例

  • URL:^((http|https)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?&=/%#.]*)?$
  • Email:^\\w+([-+.]\\w+)*@\\w+([-.]\w+)*\\.\\w+([-.]\\w+)*$
  • 整数或小数:^[+-]?([1-9]\\d*|0)(\\.\\d+)?$

Java正则表达式三个常用类

Pattern类

pattern对象是一个正则表达式对象。Pattern类没有公共构造方法。要创建一个Pattern对象,调用其公共静态方法,它返回一个Pattern对象。该方法接收一个正则表达式作为它的第一个参数。比如:Pattern r = Pattren.compile(pattren);

  • matches

    public static boolean matches(String regex, CharSequence input),检查是否整体匹配成功

Matcher类

Matcher对象是对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共构造方法,需要调用Pattern对象的matcher方法来获得一个Matcher对象。

  • 方法一览

    方法说明
    public int start()返回以前匹配的初始索引
    public int start(int group)返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引。
    public int end()返回最后匹配字符之后的偏移量
    public int end(int group)返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。
    public boolean lookingAt()尝试将从区域开头的输入序列与该模式匹配。
    public boolean find()尝试查找与该模式匹配的输入序列的下一个子序列
    public boolean find(int start)重置次匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列
    public boolean matches尝试将整个区域与模式匹配
    public Matcher appendReplacement(StringBuffer sb, String replacement)实现非终端添加和替换步骤
    public StringBuffer appendTail(StringBuffer sb)实现终端添加和替换步骤
    public String replace All(String replacement)替换模式与给定替换字符串相匹配的输入序列的每个子序列
    public String replaceFirst(String replacement)替换模式与给定替换字符串匹配的输入序列的第一个子序列
    public static String quoteReplacement(String s)返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement方法一个字面字符串一样工作

PatternSyntaxException

PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

String类中使用正则表达式

替换功能

  • public String replaceAll(String regex, String replacement)

    例:content = content.replaceAll("JDK1\\.3|JDK1\\.4", "JDK")

判断功能

  • public boolean matches(String regex)

    该方法是整体匹配。

    例:content.matches("1(28|39)\\d{8}")

分割功能

  • public String[] split(String regex)

    例:String[] split = content.split("#|-|~|\\d+");