什么是正则表达式

  • 格式:doc
  • 大小:68.50 KB
  • 文档页数:8

什么是正责表达式? 第 1 页(共9 页)

正责表达式 实质上是一个模式,用于描述共享该模式的一组字符串。例如,以下是一组包含一些常见事物的字符串:

 a string

 a longer string

 a much longer string

这些字符串中的每个字符串都是以“a”开头并以“string”结尾。Java Regular Expression

API 会帮您作出判断,结果确实非常有趣。

Java language Regular Expression(或 regex)API 非常类似于可在 Perl 语言中使用的 regex 工具。如果您是一位 Perl 编程人员,那么您应该有宾至如归的感觉,至少对

Java 语言 regex 模式语法的感觉会是这样。不过,如果不习惯于使用 regex,那么

regex 看起来可能让您感觉有点怪异。别担心,regex 并不像它看起来的那样复杂。

regex API 第 2 页(共9 页)

Java 语言的 regex 功能有三个核心类,您几乎将一直使用它们:

 Pattern,描述了一个字符串模式。

 Matcher,测试字符串,查看它是否与模式匹配。

 PatternSyntaxException,在您试着定义模式时告诉您哪些与该模式有关的地方是不可接受的。

使用示例是了解 regex 的最好方法,因此,在这一节中,我们将在

CommunityApplication.main() 中创建一个简单的示例。不过,在这样做之前,了解一些

regex 模式语法也很重要。我们将在下一屏中更详细地讨论这些。

模式语法 第 3 页(共9 页)

regex 模式 描述了表达式试图在输入字符串中查找的字符串的结构。这正是正责表达式看起来可能有点奇怪的地方。一旦了解了该语法,它也就变得没那么难以解读。

以下是一些可以在模式字符串中使用的最常见的模式构造: 构造 什么才是合格的匹配

. 任何字符

? 以前的零(0)或壹(1)。

* 以前的零(0)或其他数字。

+ 以前的壹(1)或其他数字。

[] 字符或数字的范围。

^ 否定情况(也就是说,“不是 ”)。

\d 任何数字(可以用 [0-9] 替换)。

\D 任何非数字(可以用 [^0-9] 替换)。

\s 任何空白字符(可以用 [ \n\t\f\r] 替换)。

\S 任何非空白字符(可以用 [^ \n\t\f\r] 替换)。

\w 任何单词字符(可以用 [a-zA-Z_0-9] 替换)。

\W 任何非单词字符(可以用 [^\w] 替换)。

这里的前几个构造叫做量词,因为它们将确定以前的字符数量。与 \d 类似的构造是预定义的字符类。任何在模式中没有特殊意义的字符都是一个文字,它们是自行匹配的。

匹配 第 4 页(共9 页)

在了解模式之后,下面给出了一个在 Java Regular Expression API 中使用类的简单代码示例:

Pattern pattern = pile("a.*string");

Matcher matcher = pattern.matcher("a string");

boolean didMatch = matcher.matches();

System.out.println(didMatch);

int patternStartIndex = matcher.start();

System.out.println(patternStartIndex);

int patternEndIndex = matcher.end();

System.out.println(patternEndIndex);

首先,我们将创建一个 Pattern。通过调用 compile() 可以做到这一点,compile() 是

Pattern 上的一个静态方法,它使用一个字符串文字来表示我们想匹配的模式。这个字符串文字使用的是 regex 模式语法,我们现在已经对该语法有所了解。在该例中,这种模式的英语翻译是:“找到一个字符串,该字符串以„a‟开头,然后是零个或多个字符,最后以„string‟结尾”。

接下来,将调用 Pattern 上的 matcher()。这个调用将创建一个 Matcher 实例。在发生这些的时候,Matcher 会搜索为了匹配创建 Pattern 所使用的模式字符串而传入的字符串。正如您所知道的,每个 Java 语言字符串都是一个引用的字符集,以 0 开始,并以该字符串长度减去 1 的数值结束。Matcher 从 0 开始解析字符串,并根据模式寻找匹配的字符串。

在完成这个过程之后,Matcher 将包含有关输入字符串中找到(或未找到)的匹配字符串的信息。我们可以通过调用 Matcher 上的各种方法来访问该信息:

 matches() 只告诉我们整个输入顺序是否与模式严格匹配。

 start() 告诉我们所匹配字符串起始的那个字符串中的索引值。

 end() 告诉我们所匹配字符串终止的那个字符串中的索引值,并用该值减去 1。

在这个简单的示例中,只有一个匹配字符串,该字符串以 0 开始,以 7 结束。这样,调用 matches() 就会返回 true,调用 start() 会返回 0,而调用 end() 则会返回 8。如果字符串中的字符多于我们搜索的模式中的字符,那么可以使用 lookingAt() 来代替

matches()。lookingAt() 将搜索与模式匹配的子字符串。例如,可以考虑下面这个字符串:

Here is a string with more than just the pattern.

如果使用 lookingAt() 进行搜索,那么可以搜索 a.*string 的字符串,并获得一个匹配的字符串。如果使用 matches() 进行搜索,那么将返回 false,因为字符串中的字符不会超过模式中的字符。

复杂模式 第 5 页(共9 页)

简单的搜索使用 regex 类很容易完成,但可能需要更多的技巧。

您可能熟悉 wiki,它是一个基于 Web 的系统,允许用户修改网页来“扩充”站点。无论是使用 Java 语言编写的 wiki,还是不是使用 Java 语言编写的 wiki,都几乎完全以正责表达式为基础。wiki 的内容基于用户输入的字符串,该字符串是通过正责表达式来解析和格式化的。wiki 最突出的特性之一是:通过输入 wiki 单词,任何用户都可以创建到 wiki

中另一个主题的链接,wiki 单词通常是一系列连在一起的单词,每个单词都以一个大写字母开始,如下所示:

MyWikiWord

假定有以下这样一个字符串:

Here is a WikiWord followed by AnotherWikiWord, then

YetAnotherWikiWord.

您可以利用 regex 模式搜索这个字符串中的 wiki 单词,如下所示:

[A-Z][a-z]*([A-Z][a-z]*)+

可以用以下这些代码来搜索 wiki 单词:

String input = "Here is a WikiWord followed by AnotherWikiWord, then

SomeWikiWord.";

Pattern pattern = pile("[A-Z][a-z]*([A-Z][a-z]*)+");

Matcher matcher = pattern.matcher(input);

while (matcher.find()) {

System.out.println("Found this wiki word: " +

matcher.group());

}

您应该在控制台中看到三个 wiki 单词。

替换 第 6 页(共9 页)

搜索匹配字符串很有用,一旦发现一个匹配字符串,还可以对该字符串进行操作。通过使用其他字符串替换匹配的字符串可以做到这一点,就像您可能在一个单词处理程序中搜索一些文本,并使用其他文本替换这些文本那样。Matcher 上的一些方法对我们会有所帮助:

 replaceAll(),使用我们指定的一个字符串替换所有匹配字符串。

 replaceFirst(),只使用我们指定的一个字符串替换第一个匹配字符串。

使用这些方法很简单:

String input = "Here is a WikiWord followed by AnotherWikiWord, then

SomeWikiWord.";

Pattern pattern = pile("[A-Z][a-z]*([A-Z][a-z]*)+");

Matcher matcher = pattern.matcher(input);

System.out.println("Before: " + input);

String result = matcher.replaceAll("replacement");

System.out.println("After: " + result);

这个代码将和以前一样查找 wiki 单词。当 Matcher 发现一个匹配单词时,它就会使用

replacement 替换这个 wiki 单词文本。在运行这个代码时,应该在控制台上看到以下内容:

Before: Here is WikiWord followed by AnotherWikiWord, then

SomeWikiWord.

After: Here is replacement followed by replacement, then replacement.

如果使用的是 replaceFirst(),那么将看到以下内容:

Before: Here is a WikiWord followed by AnotherWikiWord, then

SomeWikiWord.

After: Here is a replacement followed by AnotherWikiWord, then

SomeWikiWord.

组 第 7 页(共9 页)