随笔-26  评论-111  文章-19  trackbacks-0

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

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

概要

文本处理经常涉及的根据一个pattern的匹配。尽管javacharacterassorted String类提供了low-levelpattern-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通过characterassorted 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和其它的操作系统,在那里正则表达式被经常用作在UnixUnix-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 包通过PatternMatcher类和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