Java-正则表达式

Java-正则表达式

正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作。

String类提供的几个特殊方法

判断字符串是否匹配指定的正则表达式
boolean matches(String regex)
所有匹配regex的子串替换replacement
String replaceAll(String regex, String replacement)
将第一个匹配regex的子串替换成replacement
String replaceFirst(String regex, String replacement)
以regex作为分隔符,把该字符串分割为多个子串
String[] split(String regex)

Java提供了Pattern和Matcher两个类专门用于提供正则表达式

创建正则表达式

正则表达式中特殊字符

特殊字符说明
$匹配一行的结尾
^匹配一行的开头
( )标记子表达式的开始和结束位置
[ ]用于确定中括号表达式的开始和结束位置
{ }用于指定前面子表达式的出现频度
*指定前面子表达式可以出现零次或者多次
+指定前面子表达式可以出现一次或多次
?指定前面子表达式可以出现零次或一次
.匹配出了换行符\n之外的任何单字符
\用于转义下一个字符,或指定八进制、十六进制字符
|指定两项之间任选一项
如果要匹配这些特殊字符,首先将这些字符进行转义,也就是在前面加一个反斜杠(\)
即匹配 ^ 本身需要使用 ^

正则表达式的“通配符”,预定义字符

预定义字符说明
.可以匹配任何字符
\d匹配0~9的所有数字
\D匹配非数字
\s匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等
\S匹配所有非空白字符
\w匹配所有单词字符,包括0~9所有数字、26个英文字母和下画线(_)
\W匹配所有非单词字符
d 表示 digit ,代表数字
s 表示 space , 代表空白
w 是 word, 代表字母
d、s、w 的大写形式恰好匹配与之相反的字符
c\\wt //可以匹配cat、cbt、c9t、c_t 等一批字符
\\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d  //匹配如 000-000-0000 形式的电话号码

方括号表达式

方括号表达式说明
表示枚举例如[abc],表示 a、b、c 其中任意一个字符;
表示范围: -例如[a-f],表示 a~f 范围内任意字符,范围可枚举结合,如[a-cx-z]匹配ac,xz任意字符
表示求否: ^例如[ ^abc ],表示非a、b、c的任意字符;[ ^a-f] 表示不是a~f范围内的任意字符
表示“与”运算: &&例如[a-z&&[def]],求a~z和[def]的交集; [a-z&&[ ^m-p]]求a~z的所有字符除了m-p范围外
表示“并”运算并运算与前面的枚举类似,例如[a-d[m-p]],表示[a-dm-p]
若需要匹配所有的中文字符,就可以利用[\ \u0041-\ \u0056]形式

因为所有中文字符的Unicode值是连续的,只要找出所有中文字符中最小、最大的Unicode值,就可以利用上方形式来匹配所有的中文字符

边界匹配符

边界匹配符说明
^行的开头
$行的结尾
\b单词的边界
\B非单词的边界
\A输入的开头
\G前一个匹配的结尾
\Z输入的结尾,仅用于最后的结束符
\z输入的结尾

三种模式的数量表示符

Greedy(贪婪模式):数量表示符默认采用贪婪模式,除非另有表示。贪婪模式的表达式会一直匹配下去,直到无法匹配为止。
Relcutant(贪婪模式):用问好后缀(?)表示,它只会匹配最少的字符。
Possessive(占有模式):用加号后缀(+)表示,目前只有Java支持占有模式,通常比较少用
贪婪模式勉强模式占用模式说明
X?X??X?+X表达式出现零次或者一次
X*X*?X*+X表达式出现零次或者多次
X+X+?X++X表达式出现一次或者多次
X{n}X{n}?X{n}+X表达式出现n次
X{n,}X{n,}?X{n,}+X表达式最少出现n次
X{n,m}X{n,m}?X{n,m}+X表达式最少出现n次,最多出现m次

使用正则表达式

一旦在程序中定义了正则表达式,就可以是用Pattern和Matcher来使用正则表达式
Pattern对象是正则表达式编译后在内存中的表达形式,因此,正则表达式字符串必须先被编译成Pattern对象,然后再利用Pattern对象创建对应的Matcher对象。
执行匹配所涉及的状态保留在Matcher对象中,多个Matcher对象可共享同一个Pattern对象。
因此,典型的调用顺序如下:
// 将一个字符串编译成Pattern对象
Pattern p = Pattern.compile("a*b");
// 使用Pattern对象创建Matcher对象
Matcher m = p.matcher("aaaaab");
boolean b = m.matches(); // 返回true
如果正则表达式仅需要一次使用
boolean b = Pattern.matches("a*b","aaaaab"); //返回true
Pattern是不可变类,可供多个并发线程安全使用

Matcher类提供了几个常用方法

find(); 返回目标字符串中是否包含于Pattern匹配的子串
group(); 返回上一次与Pattern匹配的子串
start(); 返回上一次与Pattern匹配的子串在目标字符串中的开始位置
end(); 返回上一次与Pattern匹配的子串在目标字符串中的结束位置加一
lookingAt(); 返回目标字符串前面部分与Pattern是否匹配
matches(); 返回整个目标字符串与Pattern是否匹配
reset(); 将现有的Matcher对象应用于一个新的字符序列

程序示范

FindGroup.java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FindGroup {
	public static void main(String[] args) {
		// 使用字符串模拟从网络上得到的网页源码
		String str = "我想求购一本《疯狂Java讲义》,尽快联系我13500006666" + "交朋友,电话号码是13611125565" + "出售二手电脑,联系方式15899903312";
		// 创建一个Pattern对象,并用它建立一个Matcher对象
		// 该正则表达式只抓取13X和15X段的手机号,
		// 实际要抓取哪些电话号码,只要修改正则表达式即可。
		Matcher matcher = Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);
		while (matcher.find()) {
			System.out.println(matcher.group());
		}
	}
}
/*
13500006666
13611125565
15899903312
*/

StartEnd.java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StartEnd {
	public static void main(String[] args) {
		// 创建一个Pattern对象,并用它建立一个Matcher对象
		String regStr = "Java is very easy!";
		System.out.println("目标字符串是:" + regStr);
		Matcher m = Pattern.compile("\\w+").matcher(regStr);
		while (m.find()) {
			System.out.println(m.group() + "子串的起始位置:" + m.start() + ",其结束位置:" + m.end());
		}
	}
}
/*
目标字符串是:Java is very easy!
Java子串的起始位置:0,其结束位置:4
is子串的起始位置:5,其结束位置:7
very子串的起始位置:8,其结束位置:12
easy子串的起始位置:13,其结束位置:17
*/

MatchesTest.java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MatchesTest {
	public static void main(String[] args) {
		String[] mails = { "kongyeeku@163.com", "kongyeeku@gmail.com", "ligang@crazyit.org", "wawa@abc.xx" };
		String mailRegEx = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
		Pattern mailPattern = Pattern.compile(mailRegEx);
		Matcher matcher = null;
		for (String mail : mails) {
			if (matcher == null) {
				matcher = mailPattern.matcher(mail);
			} else {
				matcher.reset(mail);
			}
			String result = mail + (matcher.matches() ? "是" : "不是") + "一个有效的邮件地址!";
			System.out.println(result);
		}
	}
}
/*
kongyeeku@163.com是一个有效的邮件地址!
kongyeeku@gmail.com是一个有效的邮件地址!
ligang@crazyit.org是一个有效的邮件地址!
wawa@abc.xx不是一个有效的邮件地址!
*/

ReplaceTest.java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReplaceTest {
	public static void main(String[] args) {
		String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",
				"Java represses oracular expressions" };
		Pattern p = Pattern.compile(" re\\w*");
		Matcher matcher = null;
		for (int i = 0; i < msgs.length; i++) {
			if (matcher == null) {
				matcher = p.matcher(msgs[i]);
			} else {
				matcher.reset(msgs[i]);
			}
			System.out.println(matcher.replaceAll("哈哈:)"));
		}
	}
}
/*
Java has哈哈:) expressions in 1.4
regular expressions now expressing in Java
Java哈哈:) oracular expressions
*/

StringReg.java

package carzy.java.codes07;

import java.util.Arrays;

public class StringReg {
	public static void main(String[] args) {
		String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",
				"Java represses oracular expressions" };
		for (String msg : msgs) {
			System.out.println(msg.replaceFirst("re\\w*", "哈哈:)"));
			System.out.println(Arrays.toString(msg.split(" ")));
		}
	}
}
/*
Java has 哈哈:) expressions in 1.4
[Java, has, regular, expressions, in, 1.4]
哈哈:) expressions now expressing in Java
[regular, expressions, now, expressing, in, Java]
Java 哈哈:) oracular expressions
[Java, represses, oracular, expressions]
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值