📄 java.regex.tutorial.html
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="author" content="CSDN bao110908">
<meta name="description" content="Java Regex Tutorial translated from Java Tutorial">
<link rel="stylesheet" href="resource/style.css" type="text/css">
<script type='text/javascript' src='resource/javascript.js'></script>
<title>Java正则表达式教程</title>
</head>
<style type="text/css">
</style>
<body id="body">
<div>
<table align="center" class="text"><tr><td>
<div id="h1"> Java正则表达式教程 <a name="note_01"></a><sup><a href="#note01">[1]</a></sup><br/>
<span id="h1b">Regular Expressions of Java Tutorial</span></div>
<div id="h2"><a name="foreword"></a>译者序</div>
正则表达式善于处理文本,对匹配、搜索和替换等操作都有意想不到的作用。正因如此,正则表达式现在是作为程序员七种基本技能之一<a name="noteStart_01"></a><sup><a href="#noteStart01"><font size="5pt">*</font></a></sup>,因此学习和使用它在工作中都能达到很高的效率。<br/>
正则表达式应用于程序设计语言中,首次是出现在 Perl 语言,这也让 Perl 奠定了正则表达式旗手的地位。现在,它已经深入到了所有的程序设计语言中,在程序设计语言中,正则表达式可以说是标准配置了。<br/>
Java 中从 JDK 1.4 开始增加了对正则表达式的支持,至此正则表达式成为了 Java 中的基本类库,使用时不需要再导入第三方的类库了。Java 正则表达式的语法来源于象征着正则表达式标准的 Perl 语言,但也不是完全相同的,具体的可以参看 Pattern 类的 API 文档说明。<br/>
我在一次偶然中发现了位于 <a href="http://java.sun.com" target="_blank">java.sun.com</a> 站点上的 <a href="http://java.sun.com/docs/books/tutorial/" target="_blank"><cite>Java Tutorial</cite></a>,也在那里看到了关于 Java 的正则表达式教程,感觉它不同于其他的正则表达式教程,文中以大量的匹配实例来进行说明。为了能让 Java 学习者能更好地使用正则表达式,就将其完整地译出了。该教程中所介绍的正则表达式应用仅仅是最为简单的(并没有完全地涉及到 Pattern 类支持的所有正则表达式语法,也没有涉及到高级的应用),适合于从未接触过或者是尚未完全明白正则表达式基础的学习者。在学习完该教程后,应该对正则表达式有了初步的了解,并能熟练地运用 java.util.regex 包中的关于正则表达式的类库,为今后学习更高级的正则表达式技术奠定良好的基础。<br/>
教程中所有的源代码都在 src 目录下,可以直接编译运行。由于当前版本的 <a href="http://java.sun.com/docs/books/tutorial/" target="_blank"><cite>Java Tutorial</cite></a> 是基于 JDK 6.0 的,因此其中的示例程序也用到了 JDK 6.0 中的新增类库,但正则表达式在 JDK 1.4 就已经存在了,为了方便大家使用,改写了部分的源代码,源代码类名中后缀为“V4”的表示用于 JDK 1.4 或以上版本,“V5”的表示用于 JDK 5.0 或以上版本,没有这些后缀的类在各个版本中均可以正常使用。<br/>
由于译者的水平和技术能力有限,译稿虽经多次校对,难免有疏漏之处,敬请大家批评和指正。若有发现不妥之处,请发送邮件至 <a href="mailto: FrankieGao123@gmail.com">FrankieGao123@gmail.com</a>,我会在 <a href="http://blog.csdn.net/bao110908" target="_blank">blog</a> 中进行勘误,谢谢!<br/>
<p/>
火龙果顿首!<p/>
<div style="text-align: right; padding-bottom: 20px; margin-right: 24pt;">
2008 年 2 月 27 日</div><p/><p/>
<hr width="25%" align="left"><br/>
<p id="note"> <a name="noteStart01"></a><a href="#noteStart_01">*</a>
这是由《程序员》杂志社评出的,刊登在《程序员》2007 年 3 月刊上。这七种基本技能是:数组,字符串与哈希表、正则表达式、调试、两门语言、一个开发环境、SQL 语言和编写软件的思想。
</p>
<div id="h2"><a name="contents"></a>目录</div>
<div id="contents">
<ul>
<li><a href="#foreword">译者序</a></li>
<li><a href="#preface">序</a></li>
<li><a href="#reg0">0 引言</a>
<ul>
<li><a href="#reg0_1">0.1 什么是正则表达式?</a></li>
<li><a href="#reg0_2">0.2 java.util.regex 包是如何描述正则表达式的?</a></li>
</ul>
</li>
<li><a href="#reg1">1 测试用具</a></li>
<li><a href="#reg2">2 字符串</a>
<ul>
<li><a href="#reg2_1">2.1 元字符</li>
</ul>
</li>
<li><a href="#reg3">3 字符类</a>
<ul>
<li><a href="#reg3_1">3.1 简单类</a>
<ul>
<li><a href="#reg3_1_1">3.1.1 否定</a></li>
<li><a href="#reg3_1_2">3.1.2 范围</a></li>
<li><a href="#reg3_1_3">3.1.3 并集</a></li>
<li><a href="#reg3_1_4">3.1.4 交集</a></li>
<li><a href="#reg3_1_5">3.1.5 差集</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#reg4">4 预定义字符类</a></li>
<li><a href="#reg5">5 量词</a>
<ul>
<li><a href="#reg5_1">5.1 零长度匹配</a></li>
<li><a href="#reg5_2">5.2 捕获组和字符类中的量词</a></li>
<li><a href="#reg5_3">5.3 贪婪、勉强和侵占量词间的不同</a></li>
</ul>
</il>
<li><a href="#reg6">6 捕获组</a>
<ul>
<li><a href="#reg6_1">6.1 编号方式</a></li>
<li><a href="#reg6_2">6.2 反向引用</a></li>
</ul>
</li>
<li><a href="#reg7">7 边界匹配器</a></li>
<li><a href="#reg8">8 Pattern 类的方法</a>
<ul>
<li><a href="#reg8_1">8.1 使用标志构建模式</a></li>
<li><a href="#reg8_2">8.2 内嵌标志表达式</a></li>
<li><a href="#reg8_3">8.3 使用 matches(String, CharSequence) 方法</a></li>
<li><a href="#reg8_4">8.4 使用 split(String) 方法</a></li>
<li><a href="#reg8_5">8.5 其他有用的方法</a></li>
<li><a href="#reg8_6">8.6 在 java.lang.String 中等价的 Pattern 方法</a></li>
</ul>
</li>
<li><a href="#reg9">9 Matcher 类的方法</a></li>
<ul>
<li><a href="#reg9_1">9.1 使用 start 和 end 方法</a></li>
<li><a href="#reg9_2">9.2 使用 matches 和 lookingAt 方法</a></li>
<li><a href="#reg9_3">9.3 使用 replaceFirst(String) 和 replaceAll(String) 方法</a></li>
<li><a href="#reg9_4">9.4 使用 appendReplacement(StringBuffer, String) 和 appendTail(StringBuffer) 方法</a></li>
<li><a href="#reg9_5">9.5 在 java.lang.String 中等价的 Matcher 方法</a></li>
</ul>
</li>
<li><a href="#reg10">10 PatternSyntaxException 类的方法</a></li>
<li><a href="#reg11">11 更多的资源</a></li>
<li><a href="#reg12">12 问题和练习</a></li>
<li><a href="#note">注释</a></li>
<li><a href="#last">译后记</a></li>
</ul></div>
<div id="h2"><a name="preface"></a>序<span class="returnContents"><a href="#contents">返回目录</a></span></div>
本文介绍如何使用 java.util.regex API 作为正则表达式模式匹配。虽然说这个包中可被接受的语法参数与 Perl 是相似的,但我们并不需要掌握 Perl 的语法知识。本教程将从基础开始,逐层深入到更多的高级技巧。下面是各章节的主要内容:<br/>
<div id="h4">0 引言</span></div>
粗略地看一下正则表达式,同时也介绍组成 API 的核心类。<br/>
<div id="h4">1 测试用具</span></div>
编写了一个简单的应用程序,用于测试正则表达式的模式匹配。<br/>
<div id="h4">2 字符串</span></div>
介绍基本的模式匹配、元字符和引用。<br/>
<div id="h4">3 字符类</span></div>
描述简单字符类、否定、范围、并集、交集和差集。<br/>
<div id="h4">4 预定义字符类</span></div>
描述空白字符、字母和数字字符等基本的预定义字符。<br/>
<div id="h4">5 量词</span></div>
使用贪婪(greedy)、勉强(reluctant)和侵占(possessive)量词,来匹配指定表达式 X 的次数。<br/>
<div id="h4">6 捕获组</span></div>
解释如何把多个字符作为一个单独的单元进行处理。<br/>
<div id="h4">7 边界匹配器</span></div>
描述行、单词和输入的边界。<br/>
<div id="h4">8 Pattern 类的方法</span></div>
测试了 Pattern 中一些有用的方法,以及探究一些高级的特性,诸如:带标记的编译和使用内嵌标记表达式。<br/>
<div id="h4">9 Matcher 类的方法</span></div>
描述了 Matcher 类中通常使用的方法。<br/>
<div id="h4">10 PatternSyntaxException 类的方法</span></div>
描述了如何检查一个 PatternSyntaxException 异常。<br/>
<div id="h4">11 更多的资源</span></div>
要了解更多正则表达式,可以参考这一节。<br/>
<div id="h4">12 问题和练习</span></div>
巩固一下本教程所介绍的正则表达式的基本知识,并附有答案。<br/><br/>
为了区分文档中的正则表达式和普通字符串,均以<code>\d[abc]{2}</code>的形式表示正则表达式的模式。<br/>
<div id="h2"><a name="reg0"></a>0 引言<span class="returnContents"><a href="#contents">返回目录</a></span></div>
<div id="h3"><a name="reg0_1"></a>0.1 什么是正则表达式?<span class="returnContents"><a href="#contents">返回目录</a></span></div>
<em>正则表达式</em>(regular expressions)是一种描述字符串集的方法,它是以字符串集中各字符串的共有特征为依据的。正则表达式可以用于搜索、编辑或者是操作文本和数据。它超出了 Java 程序设计语言的标准语法,因此有必要去学习特定的语法来构建正则表达式。正则表达式的变化是复杂的,一旦你理解了它们是如何被构造的话,你就能解析或者构建任意的正则表达式了。<br/>
本教程讲授 java.util.regex API 所支持的正则表达式语法,以及介绍几个可运行的例子来说明不同的对象间是如何交互的。在正则表达式的世界中,有不同风格的选择,比如:grep<a name="note_02"></a><sup><a href="#note02">[2]</a></sup>、Perl、Tcl、Python、PHP 和 awk。java.util.regex API 中的正则表达式语法与 Perl 中的最为相似。<br/>
<div id="h3"><a name="reg0_2"></a>0.2 java.util.regex 包是如何描述正则表达式的?<span class="returnContents"><a href="#contents">返回目录</a></span></div>
java.util.regex 包主要由三个类所组成:Pattern、Matcher 和 PatternSyntaxException。<br/>
<ul id="ulItem">
<li id="item">Pattern 对象表示一个已编译的正则表达式。Pattern 类没有提供公共的构造方法。要构建一个模式,首先必须调用公共的静态 compile 方法,它将返回一个 Pattern 对象。这个方法接受正则表达式作为第一个参数。本教程的开始部分将教你必需的语法。</li>
<li id="item">Matcher 是一个靠着输入的字符串来解析这个模式和完成匹配操作的对象。与 Pattern 相似,Matcher 也没有定义公共的构造方法,需要通过调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。</li>
<li id="item">PatternSyntaxException 对象是一个未检查异常,指示了正则表达式中的一个语法错误。</li>
</ul>
本教程的最后几节课程会详细地说明各个类。首当其冲的问题是:必须理解正则表达式是如何被构建的,因此下一节引入了一个简单的测试用具,重复地用于探究它们的语法。
<div id="h2"><a name="reg1"></a>1 测试用具<span class="returnContents"><a href="#contents">返回目录</a></span></div>
这节给出了一个可重用的测试用具 <a href="src/RegexTestHarness.java">RegexTestHarness.java</a>,用于探究构建 API 所支持的正则表达式。使用<br/>
<pre id="console">java RegexTestHarness</pre>
这个命令来运行,没有被接受的命令行参数。这个应用会不停地循环执行下去<a name="note_03"></a><sup><a href="#note03">[3]</a></sup>,提示用户输入正则表达式和字符串。虽然说使用这个测试用具是可选的,但你会发现它用于探究下文所讨论的测试用例将更为方便。
<pre name="java" id="java">import java.io.Console;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexTestHarness {
public static void main(String[] args) {
Console console = System.console();
if (console == null) {
System.err.println("No console.");
System.exit(1);
}
while (true) {
Pattern pattern = Pattern.compile(console.readLine("%nEnter your regex: "));
Matcher matcher = pattern.matcher(console.readLine("Enter input string to search: "));
boolean found = false;
while (matcher.find()) {
console.format("I found the text \"%s\" starting at index %d " +
"and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end());
found = true;
}
if (!found) {
console.format("No match found.%n");
}
}
}
}</pre>
在继续下一节之前,确认开发环境支持必需的包,并保存和编译这段代码。
<div id="h4">【译者注】</span></div>
由于当前版本的 <a href="http://java.sun.com/docs/books/tutorial/" target="_blank"><cite>Java Tutorial</cite></a> 是基于 JDK 6.0 编写的,上述的测试用具由于使用到 JDK 6.0 中新增的类库(java.io.Console),所以该用具只能在 JDK 6.0 的环境中编译运行,由于 Console 访问操作系统平台上的控制台,因此这个测试用具只能在操作系统的字符控制台中运行,不能运行在 IDE 的控制台中。<br/>
正则表达式是 JDK 1.4 所增加的类库,为了兼容 JDK 1.4 和 JDK 5.0 的版本,重新改写了这个测试用具,让其能适用于不同的版本。<br/>
JDK 5.0 适用的测试用具(<a href="src/RegexTestHarnessV5.java">RegexTestHarnessV5.java</a>,该用具可以在 IDE 中执行),建议 JDK 6.0 环境也采用该用具。<br/>
<pre name="java" id="java">import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTestHarnessV5 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.printf("%nEnter your regex: ");
Pattern pattern = Pattern.compile(scanner.nextLine());
System.out.printf("Enter input string to search: ");
Matcher matcher = pattern.matcher(scanner.nextLine());
boolean found = false;
while (matcher.find()) {
System.out.printf(
"I found the text \"%s\" starting at index %d and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end()
);
found = true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -