正则表达式简化模式匹配的代码探索在文本处理场合下涉及模式匹配中正则表达式的优雅之处。概要文本处理经常涉及的根据一个pattern的匹配。尽管java的character和assorted的String类提供了low-level的pattern-matching支持,这种支持一般带来了复杂的代码。为了帮助你书" />

java正则表达式; regular expression

系统 1771 0

Java 101 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

正则表达式简化模式匹配的代码

探索在文本处理场合下涉及模式匹配中正则表达式的优雅之处。

概要

文本处理经常涉及的根据一个 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; <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><date year="2003" day="7" month="2"><b><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: SimSun; mso-font-kerning: 0pt">February 7, 2003</span></b></date> )

By Jeff Friesen Translated By humx

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 453.75pt; HEIGHT: 1.5pt" alt="" type="#_x0000_t75"><imagedata o:href="http://www.javaworld.com/images/rule_ltblue.gif" src="file:///C:%5CDOCUME~1%5Chumi%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.png"><font color="#990033"></font></imagedata></shape> 文本处理经常的要求依据特定 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

Foundox
starting at index 39 and ending at index 42

这个输出展示了两个 matches:fox ox . metacharacter 在第一个 match 中匹配 f ,在第二个 match 中匹配空格。

假如我们用前述的 metacharacter 替换 .ox 会怎么样呢?也就是,我们指定 java RegexDemo . "The quick brown fox jumps over the lazy ox." 会有什么样的输出,因为 period metacharacter 匹配任何字符, RegexDemo 在命令行输出每一个匹配字符,包括结尾的 period 字符。

Tip

为了指定 . 或者任何的元字符作为在一个 regex construct 作为 literal character 引用 转换 meta 状态到 literal status— 用以下两种方法之一:

  • 在元字符之前放置反斜杠。

  • 将元字符放在 \Q \E 之间(例如: \Q.\E )。

在每种情形下,不要忘记在 string literal (例如: String regex = \\.;

)中出现时(像 \\. or \\Q.\\E )的双倍的反斜杠。不要在当它在命令行参数中出现的时候用双倍的反斜杠。

Character classes

有时我们限定产生的 matches 到一个特定的字符集和。例如,我们可以检索元音 a, e, i, o, and u ,任何一个元音字符的出现都以为着一个 match A character 类, 通过在方括号之间的一个字符集和指定的 regex construct ,帮我们完成这个任务。 Pattern 支持以下的 character classes

  • 简单字符 : 支持被依次放置的字符串并仅匹配这些字符。例如: [abc] 匹配字符 a, b, and c 。以下的命令行提供了另外一个示例:

java RegexDemo [csw] cave

java RegexDemo [csw] cave [csw] c 匹配在 cave 中的 c 。没有其它的匹配存在。

  • 否定 : ^ metacharacter 元字符开始且仅匹配没有在 class 中出现的字符。例如: [^abc] 匹配所有除了 a, b, c 以外的字符,以下的命令行提供了另外一个示例:

java RegexDemo [^csw] cave

java RegexDemo [^csw] cave 匹配在 cave 中遇到的 a, v, e 。没有其它的匹配存在。

  • 范围 : 包含在元字符( - )左侧的字符开始,元字符( - )右侧字符结束的所有字符。仅匹配在范围内的字符。例如: [a-z] 匹配所有的小写字母。以下的命令行提供了另外一个示例:

java RegexDemo [a-c] clown

java RegexDemo [a-c] clown 匹配在 clown 中的 c 。没有其它的匹配存在。

margin: 0mm 0mm 0pt; text-align:

分享到:
评论
wapysun
  • 浏览: 4879226 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最新评论

java正则表达式; regular expression


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论