ITEEDU

Java Gossip: 使用正则表示式(Regular expression)

如果您查询J2SE 1.4之后String的在线API手册说明,您会发现有matches()、replaceAll()等方法,您所传入的参数是「正则表示式」(Regular expression)的字符串,正则表示式的功能是J2SE 1.4之后加入的新功能。

正则表示式最早是由数学家Stephen Kleene于1956年提出,主要使用在字符字符串的格式比对,后来在信息领域广为应用,现在已经成为ISO(国际标准组织)的标准之一。

Java在J2SE 1.4之后开始支持正则表示式,您可以在API文件的 java.util.regex.Pattern 类别中找到支持的正则表示式相关信息。

如果您使用String类别来配置字符串对象,您可以使用简易的方法来使用正则表示式,并应用于字符串的比对或取代等动作上,以下先介绍几个简单的正则表示式。

例如一些常用的范围,我们可以使用预先定义的字符类别:

.

符合任一字符

\d

等于 [0-9] 数字

\D

等于 [^0-9] 非数字

\s

等于 [ \t\n\x0B\f\r] 空格符

\S

等于 [^ \t\n\x0B\f\r] 非空格符

\w

等于 [a-zA-Z_0-9] 数字或是英文字

\W

等于 [^a-zA-Z_0-9] 非数字与英文字

符合任一字符。例如有一字符串abcdebcadxbc,使用.bc来比对的话,符合的子字符串有abc、ebc、xbc三个;如果使用..cd,则符合的子字符串只有bcd。

以上的例子来根据字符比对,您也可以使用「字符类」(Character class)来比较一组字符范围,例如:

[abc]

a、b或c

[^abc]

非a、b、c的其它字符

[a-zA-Z]

a到z或A到Z(范围)

[a-d[m-p]]

a到d或m到p(联集)

[a-z&&[def]]

d、e或f(交集)

[a-z&&[^bc]]

a到z,除了b与c之外(减集)

[a-z&&[^m-p]]

a到z且没有m到p(a-lq-z)(减集)

一次只指定一个字符不过瘾,也可以用Greedy quantifiers来指定字符可能出现的次数:

X?

X出现一次或完全没有

X*

X出现零次或多次

X+

X出现一次或多次

X{n}

X出现n次

X{n,}

X出现至少n次

X{n,m}

X出现至少n次,但不超过m次

另外还有Reluctant quantifiers、Possessive quantifiers等的指定,您可以自行参考 java.util.regex.Pattern 类别中的说明。

在String类别中,matches()方法可以让您验证字符串是否符合指定的正规表示式,这通常用于验证使用者输入的字符串数据是否正确,例如 电话号码格式;replaceAll()方法可以将符合正规表示式的子字符串置换为指定的字符串;split()方法可以让您依指定的正规表示式,将符合的子 字符串分离出来,并以字符串数组传回。

下面这个程序示范几个正则表示式的应用:

UseRegularExpression.java
import java.util.Scanner;
public class UseRegularExpression {
	public static void main(String args[]) {
		Scanner scanner = new Scanner(System.in);
		String str = "abcdefgabcabc";
		System.out.println(str.replaceAll(".bc", "###"));
		System.out.print("输入手机号码: ");
		str = scanner.next();
		// 简单格式验证
		if(str.matches("[0-9]{4}-[0-9]{6}"))
		System.out.println("格式正确");
		else
		System.out.println("格式错误");
		System.out.print("输入href标签: ");
		// Scanner的next()方法是以空白为区隔
		// 我们的输入有空白,所以要执行两次
		str = scanner.next() + " " + scanner.next();
		// 验证href标签
		if(str.matches(""<a.+href*=*['\"]?.*?['\"]?.*?>))
		System.out.println("格式正确");
		else
		System.out.println("格式错误");
		System.out.print("输入电子邮件: ");
		str = scanner.next();
		// 验证电子邮件格式
		if(str.matches(
		"^[_a-z0-9-]+([.][_a-z0-9-]+)*@[a-z0-9-]+([.][a-z0-9-]+)*$"))
		System.out.println("格式正确");
		else
		System.out.println("格式错误");
	}
}

执行结果:

###defg######
输入手机号码: 0988-100432
格式正确
输入href标签: 
格式正确
输入电子邮件: justin@caterpillar.onlyfun.net
格式正确

最后两个href标签与email验证例子是很常见的正规表示式应用,您可以仔细看看以了解如何比对,并不会特别困难。