如果查询 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
格式正确