正则表达式 #
- 正则表达式定义了字符串的模式。
- 正则表达式可以用来搜索、编辑或处理文本。
- 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
语法 #
regex包 #
java.util.regex包主要包括以下三个类:
Pattern类:- pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其公共静态方法
compile(),它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数。
- pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其公共静态方法
Matcher类:- Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的
matcher()方法来获得一个 Matcher 对象。
- Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的
PatternSyntaxException异常类:- PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
java.util.regex.Pattern #
Pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其公共静态方法compile(),它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数。
// 编译一个正则表达式
Pattern pattern = Pattern.compile("\\d+");
java.util.regex.Matcher #
Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher(CharSequence s)方法来获得一个 Matcher 对象。
// 创建字符串匹配引擎
Matcher matcher = pattern.matcher("1324");
- Matcher可以理解为匹配的迭代器, 执行上述代码后,相当于有一个匹配指针在字符序列的首位,并没有开始匹配,只有在调用
matches()或find()方法后,指针才会后移进行匹配。 - 其中
matches()方法调用后,指针会直接移动到字符序列的末尾,此时如果再调用find()方法,就无法找到匹配项了。 - 其中
find()方法调用后,指针会向后逐个匹配子字符串,如果找到就停下。
捕获组 #
捕获组是把多个字符当成一个单独单元进行处理的方法,它通过对括号()内的字符分组来创建。
例如表达式A(B(C))中,一共由三个分组ABC、BC、C
Pattern pattern = Pattern.compile("A(B(C))");
String s = "ABC";
Matcher matcher = pattern.matcher(s);
// 如果要调用group()查看分组结果,必须调用matches()或find()进行匹配,否则会有异常
System.out.println(matcher.matches());
System.out.println(matcher.groupCount()); // 2
System.out.println(matcher.group(0)); // ABC
System.out.println(matcher.group(1)); // BC
System.out.println(matcher.group(2)); // C
注意 #
- 如果调用
group()方法查看分组结果,必须是调用了matches()方法或者find()方法,并且已经匹配到了,否则会抛出异常throw new IllegalStateException("No match found"); - 有一个特殊的group:
group(0),表示了正则表达式此时的匹配结果,例如matches()方法调用后如果匹配成功,则表示整个字符串;find()方法调用后,如果匹配到子字符串,则表示这个子字符串。并且group(0)不计入groupCount()的统计结果。
引用组 #
例如,要匹配例如123-123的字符串,-前面和后面的数字不固定,但是一定相同那么就可以用引用组
// \1表示引用group(1)的字符串
Pattern pattern = Pattern.compile("(\\d+)-\\1");
String s1 = "1234-1234";
String s2 = "66-661";
Matcher matcher = pattern.matcher(s1);
System.out.println(matcher.matches()); // true
matcher.reset(s2);
System.out.println(matcher.matches()); // false
常用方法 #
matches() #
判断整个字符串是否匹配上模式,匹配上则返回true,否则false。
find() #
作用是发现字符串中所有与pattern匹配的子字符串,并且每次调用find(),都会指向下一个匹配到的字符串,并返回是否有匹配的子字符串
Pattern pattern = Pattern.compile("\\d+");
String s = "123abc456";
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
System.out.println("匹配的字符串开始位置:" + matcher.start());
System.out.println("匹配的字符串结束位置:" + matcher.end());
System.out.println("匹配的字符串:" + matcher.group());
}
start()、end() #
如果匹配成功,start()会返回此次匹配的开始位置;end()会返回此次匹配的结束位置,即最后一个字符的下标加一。
如果没有调用过matches()、find()或者未找到匹配的字符串,此时的start、end都是-1,如果调用start()、end()方法,会抛出异常throw new IllegalStateException("No match available");
reset() #
用reset(CharSequence s)方法可以给现有的Matcher对象配上个新的CharSequence。
如果不给参数,reset()会把Matcher设到当前字符串的开始处。
group() #
有一个特殊的group:group(0),表示了正则表达式此时的匹配结果,例如matches()方法调用后如果匹配成功,则表示整个字符串;find()方法调用后,如果匹配到子字符串,则表示这个子字符串。并且group(0)不计入groupCount()的统计结果。
其中matcher.group() == matcher.group(0)
常用的正则表达式 #
中文字符 #
[\u4e00-\u9fa5]+
身份证号 #
中国的身份证为15位或18位
\d{17}[\d|X]|\d{15}
IP #
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
日期 #
\d{4}[年|\-|\.]\d{1,2}[月|\-|\.]\d{1,2}日?
邮箱 #
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
URL #
((http)|(https))://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
密码 #
// 表示至少一位数字、至少一位大写字母、至少一个非单词字符,然后8-16位非空字符
^(?=.*[0-9])(?=.*[A-Z])(?=.*\W)[\S]{8,16}$