服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

java正则表达式; regular expression


  概要

文本处理经常涉及的根据一个pattern的匹配。尽管java的character和assorted 的string类提供了low-level的pattern-matching支持,这种支持一般带来了复杂的代码。为了帮助你书写简单的pattern-matching代码,java提供了regular expression。在介绍给你术语和java.util.regex包之后,jeff friesen explores 了许多那个包的pattern类支持的正则表达式结构。然后他examines 了pattern的方法和附加的java.util.regex 类。作为结束,他提供了一个正则表达式的实践应用。

为察看术语列表,提示与警告,新的homework,上个月homework的回答,这篇文章的相关材料,请访问study guide. (6,000 words; february 7, 2003)

by jeff friesen ,translated by humx

文本处理经常的要求依据特定pattern匹配的代码。它能让文本检索,email header验证,从普通文本的自定义文本的创建(例如,用"dear mr. smith" 替代 "dear customer"),等等成为可能。java通过character和assorted string类支持pattern matching。由于low-level的支持一般带来了复杂的pattern-matching代码,java同时提供了regular expression来简代码。

regular expressions经常让新手迷惑。然而, 这篇文章驱散了大部分混淆。在介绍了regular expression术语,java.util.regex 包中的类, 和一个regular expression constructs的示例程序之后, 我explore了许多pattern类支持的regular expression constructs。我也examine了组成pattern 和java.util.regex 包中其它类的方法。一个practical 的正则表达式的应用程序结束了我的讨论。

note

regular expressions的漫长历史开始于计算机科学理论领域自动控制原理和formal 语言理论。它的历史延续到unix和其它的操作系统,在那里正则表达式被经常用作在unix和unix-like的工具中:像awk(一个由其创作者,aho, weinberger, and kernighan,命名,能够进行文本分析处理的编程语言), emacs (一个开发工具),和grep (一个在一个或多个文件中匹配正则表达式,为了全局地正则表达式打印的工具。


什么是正则表达式?
a regular expression,也被known as regex or regexp,是一个描述了一个字符串集合的pattern(template)。这个pattern决定了什么样的字符串属于这个集合,它由文本字符和元字符(metacharacters,由有特殊的而不是字符含义的字符)组成。为了识别匹配的检索文本的过程―字符串满足一个正则表达式―称作模式匹配(pattern matching)。

java's java.util.regex 包通过pattern,matcher类和patternsyntaxexception异常支持pattern matching:

pattern 对象,被known as patterns,是编译的正则表达式。
matcher 对象,或者matchers,在,实现了java.lang.charsequence接口并作为文本source的字符序列中定位解释matchers的引擎。
patternsyntaxexception 对象描述非法的regex patterns。
listing 1 介绍这些类:

listing 1. regexdemo.java

// regexdemo.java
import java.util.regex.*;


class regexdemo {
public static void main (string [] args) {
if (args.length != 2)
system.err.println ("java regexdemo regex text");
return;
}
pattern p;
try {
p = pattern.compile (args [0]);
}
catch (patternsyntaxexception e) {
system.err.println ("regex syntax error: " + e.getmessage ());
system.err.println ("error description: " + e.getdescription ());
system.err.println ("error index: " + e.getindex ());
system.err.println ("erroneous pattern: " + e.getpattern ());
return;
}

string s = cvtlineterminators (args [1]);
matcher m = p.matcher (s);

system.out.println ("regex = " + args [0]);
system.out.println ("text = " + s);
system.out.println ();
while (m.find ()) {
system.out.println ("found " + m.group ());
system.out.println (" starting at index " + m.start () +
" and ending at index " + m.end ());
system.out.println ();
}
}

// convert /n and /r character sequences to their single character
// equivalents

static string cvtlineterminators (string s) {
stringbuffer sb = new stringbuffer (80);

int oldindex = 0, newindex;
while ((newindex = s.indexof ("//n", oldindex)) != -1) {
sb.append (s.substring (oldindex, newindex));
oldindex = newindex + 2;
sb.append ('/n');
}
sb.append (s.substring (oldindex));

s = sb.tostring ();

sb = new stringbuffer (80);

oldindex = 0;
while ((newindex = s.indexof ("//r", oldindex)) != -1) {
sb.append (s.substring (oldindex, newindex));
oldindex = newindex + 2;
sb.append ('/r');
}
sb.append (s.substring (oldindex));

return sb.tostring ();
}
}

regexdemo's public static void main(string [] args) 方法validates 两个命令行参数:一个指出正则表达式,另外一个指出文本。在创建一个pattern之后,这个方法转换所有的文本参数,new-line and carriage-return line-terminator 字符序列为它们的实际meanings 。例如,一个new-line字符序列(由反斜杠后跟n表示)转换成一个new-line字符(用数字表示为10)。在输出了regex和被转换的命令行文本参数之后,main(string [] args) 方法从pattern创建了一个matcher,它随后查找了所有的matches 。对于每一个match,它所出现的字符和信息的位置被输出。

为了完成模式匹配,regexdemo 调用了java.util.regex包中类的不同的方法。不要使你自己现在就理解这些方法;我们将在后边的文章探讨它们。更重要的是,编译 listing 1: 你需要regexdemo.class来探索pattern's regex 结构。

探索pattern's regex 构造

pattern's sdk 文档提供了一部分正则表达式结构的文档。除非你是一个avid正则表达式使用者,一个最初的那段文档的阅读会让你迷惑。什么是quantifiers,greedy之间的不同是什么, reluctant, 和 possessive quantifiers? 什么是 character classes, boundary matchers, back references, 和 embedded flag expressions? 为了回答这些和其它的问题,我们探索了许多patter认可的regex constructs或 regex pattern 种类。我们从最简单的regex construct 开始:literal strings。

caution

不要认为pattern和perl5的正则表达式结构是一样的。尽管他们有很多相同点,他们也有许多,它们支持的metacharacters结构的不同点。 (更多信息,察看在你的平台上的你的sdk pattern类的文档。)


literal strings

当你在字处理软件的检索对话框输入一个你指定一个literal string 的时候,你就指定了一个regex expression construct 。执行以下的regexdemo 命令行来察看一下这个regex construct 的动作:

java regexdemo apple applet

上边的这个命令行确定了apple 作为一个包含了字符a, p, p, l, and e(依次)的字符regex construct。 这个命令行同时也确定了applet 作为pattern-matching的文本。执行命令行以后,看到以下输出:

regex = apple
text = applet

found apple
starting at index 0 and ending at index 5

输出的regex 和text 命令行,预示着在applet中一个applet的成功的匹配,并表示了匹配的开始和结束的索引:分别为0和5。开始索引指出了一个pattern match出现的第一个文本的开始位置,结束索引指明了这个match后的第一个text的位置。换句话说,匹配的text的范围包含在开始索引和去掉结束索引之间(不包含结束索引)。

metacharacters

尽管string regex constructs 是有用的,更强大的regex contsruct联合了文本字符和元字符。例如,在a.b,这个句点metacharacter (.) 代表在a个b之间出现的任何字符。 为了察看元字符的动作, 执行以下命令行:

java regexdemo .ox "the quick brown fox jumps over the lazy ox."

以上命令指出.ox 作为regex ,和the quick brown fox jumps over the lazy ox.作为文本源text。regexdemo 检索text来匹配以任意字符开始以ox结束的match,并产生如下输出:

regex = .ox
text = the quick brown fox jumps over the lazy ox.

found fox
starting at index 16 and ending at index 19

扫描关注微信公众号