6.2.3 使用正则表达式(Regular Expression)
如果查询J2SE 1.4之后的String在线API手册说明,会发现有matches()、replaceAll()等方法,所传入的自变量是正则表达式(Regular Expression)的字符串。正则表达式最早是由数学家Stephen Kleene于1956年提出,主要使用在字符字符串的格式比对,后来在信息领域广为应用,现在已经成为ISO(国际标准组织)的标准之一。
Java在J2SE 1.4之后开始支持正则表达式,您可以在API文件的java.util.regex.Pattern类中找到支持的正则表达式相关信息,可以将正则表达式应用于字符串的比对、取代、分离等动作上。以下将介绍几个简单的正则表达式。
对于一些简单的字符比对,例如1~9、A~Z等,您可以使用预先定义的符号来表示。表6-4列出了几个常用的字符比对符号。
表6-4 字符比对符号
方 法 |
说 明 |
. |
符合任一字符 |
\d |
符合0~9任一个数字字符 |
\D |
符合0~9以外的字符 |
\s |
符合\t、\n、\x0B、\f、\r等空格符 |
\w |
符合a~z、A~Z、0~9等字符,也就是数字或是字母都符合 |
\W |
符合a~z、A~Z、0~9等之外的字符,也就是除数字与字母外都符合 |
举例来说,如果有一字符串abcdebcadxbc,若使用.bc来作比对,符合的子字符串有abc、ebc、xbc 3个;如果使用..cd,则符合的子字符串只有abcd。范例6.9证实了这个说明。
Ü 范例6.9 RegularExpressionDemo.java
public class RegularExpressionDemo {
public static void main(String[] args) {
String text = "abcdebcadxbc";
String[] tokens = text.split(".bc");
for(String token : tokens) {
System.out.print(token + " ");
}
System.out.println();
tokens = text.split("..cd");
for(String token : tokens) {
System.out.print(token + " ");
}
System.out.println();
}
}
执行结果:
d ad
ebcadxbc
使用.bc来作比对,由于符合的子字符串有abc、ebc、xbc 3个,所以split()方法会使用这3个字符串为依据来作字符串分离,返回的自然就是不符合表达式.bc的d与ad。同理如果表达式为..cd,则使用split()返回的就是不符合..cd的ebcadxbc。
也可以使用字符类(Character Class)来比较一组字符范围。表6-5示范了几个字符类的设定方式。
表6-5 字符类范例
范 例 |
作 用 |
[abc] |
符合a、b或c |
[^abc] |
符合a或b或c之外的字符 |
[a-zA-Z] |
符合a~z或者是A~Z的字符 |
[a-d[m-p]] |
a~d或者是m~p,也可以写成[a-dm-p] |
[a-z&&[def]] |
a~z并且是d或e或f,结果就是d或e或f可以符合 |
[a-z&&[^bc]] |
a~z并且不是b或c |
[a-z&&[^m-p]] |
a~z并且不是m~p |
指定一个字符之外,也可以加上“贪婪量词”(Greedy Quantifiers)来指定字符可能出现的次数。表6-6示范了几个例子。
表6-6 贪婪量词范例
范 例 |
作 用 |
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类API文件中的说明。
在String类中,matches()方法可以让您验证字符串是否符合指定的正则表达式,这通常用于验证使用者输入的字符串数据是否正确,例如电话号码格式;replaceAll()方法可以将符合正则表达式的子字符串置换为指定的字符串;split()方法可以让您依指定的正则表达式,将符合的子字符串排除,剩下的子字符串分离出来并以字符串数组返回。范例6.9已经示范了split()方法的使用,接下来在范例6.10中示范replaceAll()与matches()方法的运用。
Ü 范例6.10 UseRegularExpression.java
import java.io.*;
public class UseRegularExpression {
public static void main(String args[])
throws IOException {
BufferedReader reader =
new BufferedReader(
new InputStreamReader(System.in));
System.out.println("abcdefgabcabc".replaceAll(".bc", "###"));
String phoneEL = "[0-9]{4}-[0-9]{6}";
String urlEL = "<a.+href*=*['\"]?.*?['\"]?.*?>";
String emailEL = "^[_a-z0-9-]+(.[_a-z0-9-]+)*" +
"@[a-z0-9-]+([.][a-z0-9-]+)*$";
System.out.print("输入手机号码: ");
String input = reader.readLine();
if(input.matches(phoneEL))
System.out.println("格式正确");
else
System.out.println("格式错误");
System.out.print("输入href标签: ");
input = reader.readLine();
// 验证href标签
if(input.matches(urlEL))
System.out.println("格式正确");
else
System.out.println("格式错误");
System.out.print("输入电子邮件: ");
input = reader.readLine();
// 验证电子邮件格式
if(input.matches(emailEL))
System.out.println("格式正确");
else
System.out.println("格式错误");
}
}
执行结果:
###defg######
输入手机号码: 0939-100391
格式正确
输入href标签: <a href="http://caterpillar.onlyfun.net">
格式正确
输入电子邮件: caterpillar.onlyfun@gmail.com
格式正确
良葛格的话匣子:
正则表达式的设计是一门学问,也有专门的书籍就是在介绍正则表达式的设计,没有经常使用的话,很难设计出实用性高的正则表达式,这里只能说大致介绍而已。如果真有需要某种正则表达式,建议可以使用搜索引擎查看有无现成或类似的表达式可以使用,要不然的话,就只有找专门的书籍研究研究如何设计了。