正则表达式和Java编程语言

本文介绍如何在Java编程语言中使用正则表达式进行模式匹配,包括基本概念、构造正则表达式的方法及实际应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式和Java编程语言
文章目录

正则表达式和Java编程语言
by Dana Nourie and Mike McCloskey
2001年8月
2002年4月修订

应用程序常常需要有文本处理功能,比如单词查找、电子邮件确认或XML文档 集成。这通常会涉及到模式匹配。Perl、sed或awk等语言通过使用正则表达式来 改善模式匹配,正则表达式是一串字符,它所定义的模式可用来查找匹配的文本。 为了使用JavaTM编程语言进行模式匹配,需 要使用带有许多charAt子字串的StringTokenizer 类,读取字母或符号以便处理文本。这常常导致复杂或凌乱的代码。

现在不一样了。

2平台标准版(J2SETM)1.4版包含一个名 为java.util.regex的新软件包,使得使用正则表达式成为可能。 目前的功能包括元字符的使用,它赋予正则表达式极大的灵活性

本文概括地介绍了正则表达式的使用,并详细解释如何利用 java.util.regex软件包来使用正则表达式,用以下常见情形作为 例子:

 

  • 简单的单词替换
  • 电子邮件确认
  • 从文件中删除控制字符
  • 查找文件

 

为了编译这些例子中的代码和在应用程序中使用正则表达式,需要安装 J2SE 1.4版

 

构造正则表达式

 

正则表达式是一种字符模式,它描述的是一组字符串。你可以使用 java.util.regex软件包,查找、显示或修改输入序列中出现的 某个模式的一部分或全部。

正则表达式最简单的形式是一个精确的字符串,比如“Java”或 “programming”。正则表达式匹配还允许你检查一个字符串是否符合某个具体的 句法形式,比如是不是一个电子邮件地址。

为了编写正则表达式,普通字符和特殊字符都要使用:

 

/$^.*
+?['']
/.
 
   

 

正则表达式中出现的任何其他字符都是普通字符,除非它前面有个 /

特殊字符有着特别的用处。例如,.可匹配除了换行符之外的任意字符。与 s.n这样的正则表达式匹配的是任何三个字符的、以s 开始以n结束的字符串,包括sunson

在正则表达式中有许多特殊字符,可以查找一行开头的单词,忽略大小写或 大小写敏感的单词,还有特殊字符可以给出一个范围,比如a-e表 示从ae的任何字母。

使用这个新软件包的正则表达式用法与Perl类似,所以如果你熟悉Perl中正则 表达式的使用,就可以在Java语言中使用同样的表达式语法。如果你不熟悉正则 表达式,下面是一些入门的例子:

 

构造匹配于
 
字符 
x字符 x
//反斜线字符
/0n八进制值的字符0n (0 <= n <= 7)
/0nn八进制值的字符 0nn (0 <= n <= 7)
/0mnn八进制值的字符0mnn 0mnn (0 <= m <= 3, 0 <= n <= 7)
/xhh十六进制值的字符0xhh
/uhhhh十六进制值的字符0xhhhh
/t制表符('/u0009')
/n换行符 ('/u000A')
/r回车符 ('/u000D')
/f换页符 ('/u000C')
/a响铃符 ('/u0007')
/e转义符 ('/u001B')
/cxT对应于x的控制字符 x
 
字符类
[abc]a, b, or c (简单类)
[^abc]除了abc之外的任意 字符(求反)
[a-zA-Z]azAZ ,包含(范围)
[a-z-[bc]]az,除了bc[ad-z](减去)
[a-z-[m-p]]az,除了mp[a-lq-z]
[a-z-[^def]]d, e, 或 f
 
预定义的字符类
.任意字符(也许能与行终止符匹配,也许不能)
/d数字: [0-9]
/D非数字: [^0-9]
/s空格符: [ /t/n/x0B/f/r]
/S非空格符: [^/s]
/w单词字符: [a-zA-Z_0-9]
/W非单词字符: [^/w]

 

有关进一步的详情和例子,请参阅 Pattern类的文档

类和方法

 

下面的类根据正则表达式指定的模式,与字符序列进行匹配。

Pattern类

Pattern类的实例表示以字符串形式指定的正则表达式,其语 法类似于Perl所用的语法。

用字符串形式指定的正则表达式,必须先编译成Pattern类的 实例。生成的模式用于创建Matcher对象,它根据正则表达式与任 意字符序列进行匹配。多个匹配器可以共享一个模式,因为它是非专属的。

compile方法把给定的正则表达式编译成模式,然后用 matcher方法创建一个匹配器,这个匹配器将根据此模式对给定输 入进行匹配。pattern 方法可返回编译这个模式所用的正则表达 式。

split方法是一种方便的方法,它在与此模式匹配的位置将给 定输入序列切分开。下面的例子演示了:

 

/*
* 用split对以逗号和/或空格分隔的输入字符串进行切分。
*/
import java.util.regex.*;

public class Splitter {
public static void main(String[] args) throws Exception {
// Create a pattern to match breaks
Pattern p = Pattern.compile("[,//s]+");
// Split input with the pattern
String[] result = 
	 p.split("one,two, three   four ,  five");
for (int i=0; i<result.length; i++)
System.out.println(result[i]);
}
}

Matcher类

 

Matcher类的实例用于根据给定的字符串序列模式,对字符序 列进行匹配。使用CharSequence接口把输入提供给匹配器,以便 支持来自多种多样输入源的字符的匹配。

通过调用某个模式的matcher方法,从这个模式生成匹配器。 匹配器创建之后,就可以用它来执行三类不同的匹配操作:

 

  • matches方法试图根据此模式,对整个输入序列进行匹配。
  • lookingAt方法试图根据此模式,从开始处对输入序列进 行匹配。
  • find方法将扫描输入序列,寻找下一个与模式匹配的地方。

 

这些方法都会返回一个表示成功或失败的布尔值。如果匹配成功,通过查询 匹配器的状态,可以获得更多的信息

这个类还定义了用新字符串替换匹配序列的方法,这些字符串的内容如果需 要的话,可以从匹配结果推算得出。

appendReplacement方法先添加字符串中从当前位置到下一个 匹配位置之间的所有字符,然后添加替换值。appendTail添加的 是字符串中从最后一次匹配的位置之后开始,直到结尾的部分。

例如,在字符串blahcatblahcatblah中,第一个 appendReplacement添加blahdog。第二个 appendReplacement添加blahdog,然后 appendTail添加blah,就生成了: blahdogblahdogblah。请参见示例 简单的单词替换

CharSequence接口

CharSequence接口为许多不同类型的字符序列提供了统一的只 读访问。你提供要从不同来源搜索的数据。用String, StringBufferCharBuffer实现CharSequence,,这样就可以很 容易地从它们那里获得要搜索的数据。如果这些可用数据源没一个合适的,你可 以通过实现CharSequence接口,编写你自己的输入源。

 

Regex情景范例

 

以下代码范例演示了java.util.regex软件包在各种常见情形 下的用法:

简单的单词替换

 

/*
* This code writes "One dog, two dogs in the yard."
* to the standard-output stream:
*/
import java.util.regex.*;

public class Replacement {
public static void main(String[] args) 
			 throws Exception {
// Create a pattern to match cat
Pattern p = Pattern.compile("cat");
// Create a matcher with an input string
Matcher m = p.matcher("one cat," +
		   " two cats in the yard");
StringBuffer sb = new StringBuffer();
boolean result = m.find();
// Loop through and create a new String 
// with the replacements
while(result) {
m.appendReplacement(sb, "dog");
result = m.find();
}
// Add the last segment of input to 
// the new String
m.appendTail(sb);
System.out.println(sb.toString());
}
}

 

电子邮件确认

以下代码是这样一个例子:你可以检查一些字符是不是一个电子邮件地址。 它并不是一个完整的、适用于所有可能情形的电子邮件确认程序,但是可以在 需要时加上它。

 

/*
* Checks for invalid characters
* in email addresses
*/
public class EmailValidation {
public static void main(String[] args) 
					 throws Exception {
					 
String input = "@sun.com";
//Checks for email addresses starting with
//inappropriate symbols like dots or @ signs.
Pattern p = Pattern.compile("^//.|^//@");
Matcher m = p.matcher(input);
if (m.find())
System.err.println("Email addresses don't start" +
				" with dots or @ signs.");
//Checks for email addresses that start with
//www. and prints a message if it does.
p = Pattern.compile("^www//.");
m = p.matcher(input);
if (m.find()) {
System.out.println("Email addresses don't start" +
	" with /"www./", only web pages do.");
}
p = Pattern.compile("[^A-Za-z0-9//.//@_//-~#]+");
m = p.matcher(input);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
boolean deletedIllegalChars = false;

while(result) {
deletedIllegalChars = true;
m.appendReplacement(sb, "");
result = m.find();
}

// Add the last segment of input to the new String
m.appendTail(sb);

input = sb.toString();

if (deletedIllegalChars) {
System.out.println("It contained incorrect characters" +
			   " , such as spaces or commas.");
}
}
}

 

从文件中删除控制字符

 

/* This class removes control characters from a named
*  file.
*/
import java.util.regex.*;
import java.io.*;

public class Control {
public static void main(String[] args) 
					 throws Exception {
					 
//Create a file object with the file name
//in the argument:
File fin = new File("fileName1");
File fout = new File("fileName2");
//Open and input and output stream
FileInputStream fis = 
			  new FileInputStream(fin);
FileOutputStream fos = 
			new FileOutputStream(fout);

BufferedReader in = new BufferedReader(
		   new InputStreamReader(fis));
BufferedWriter out = new BufferedWriter(
		  new OutputStreamWriter(fos));

// The pattern matches control characters
Pattern p = Pattern.compile("{cntrl}");
Matcher m = p.matcher("");
String aLine = null;
while((aLine = in.readLine()) != null) {
m.reset(aLine);
//Replaces control characters with an empty
//string.
String result = m.replaceAll("");
out.write(result);
out.newLine();
}
in.close();
out.close();
}
}

 

文件查找

/*
* Prints out the comments found in a .java file.
*/
import java.util.regex.*;
import java.io.*;
import java.nio.*;
import java.nio.charset.*;
import java.nio.channels.*;

public class CharBufferExample {
public static void main(String[] args) throws Exception {
// Create a pattern to match comments
Pattern p = 
Pattern.compile("//.*$", Pattern.MULTILINE);

// Get a Channel for the source file
File f = new File("Replacement.java");
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();

// Get a CharBuffer from the source file
ByteBuffer bb = 
fc.map(FileChannel.MAP_RO, 0, (int)fc.size());
Charset cs = Charset.forName("8859_1");
CharsetDecoder cd = cs.newDecoder();
CharBuffer cb = cd.decode(bb);

// Run some matches
Matcher m = p.matcher(cb);
while (m.find())
System.out.println("Found comment: "+m.group());
}
}

 

结论

现在Java编程语言中的模式匹配和许多其他编程语言一样灵活了。可以在应 用程序中使用正则表达式,确保数据在输入数据库或发送给应用程序其他部分之 前,格式是正确的,正则表达式还可以用于各种各样的管理性工作。简而言之, 在Java编程中,可以在任何需要模式匹配的地方使用正则表达式。

更多信息

软件包java.util.regex

Java编程论坛

Java编程论坛

 

Dana Nourie是JDC技术方面的作家。她热衷于研究Java平台,特别是使 用服务器小程序和JavaServer Pages技术创建交互式Web应用程序,比如 JDC 测验学习之路以及 循序渐进这些页面。她还是一位潜水员,正在寻找太平洋深水海马。

Mike McCloskey 是Sun公司的一位工程师,致力于Core Libraries for J2SE(J2SE核心库)的开发。 java.lang, java.util, java.io 和,以及新软件包java.util.regexjava.nio.中 都有他的一份功劳。他喜欢打壁球和写科幻小说。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值