⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zhengzebiaodashi.txt

📁 正则表达式(regular expression)使用大全
💻 TXT
📖 第 1 页 / 共 5 页
字号:

字符集  
.  表示任意一个字符  
[abc]  表示字符a,b,c中的任意一个(与a|b|c相同)  
[^abc]  除a,b,c之外的任意一个字符(否定)  
[a-zA-Z]  从a到z或A到Z当中的任意一个字符(范围)  
[abc[hij]]  a,b,c,h,i,j中的任意一个字符(与a|b|c|h|i|j相同)(并集)  
[a-z&&[hij]]  h,i,j中的一个(交集)  
\s  空格字符(空格键, tab, 换行, 换页, 回车)  
\S  非空格字符([^\s])  
\d  一个数字,也就是[0-9]  
\D  一个非数字的字符,也就是[^0-9]  
\w  一个单词字符(word character),即[a-zA-Z_0-9]  
\W  一个非单词的字符,[^\w]  

如果你用过其它语言的正则表达式,那么你一眼就能看出反斜杠的与众不同。在其它语言里,"\\"的意思是"我只是要在正则表达式里插入一个反斜杠。没什么特别的意思。"但是在Java里,"\\"的意思是"我要插入一个正则表达式的反斜杠,所以跟在它后面的那个字符的意思就变了。"举例来说,如果你想表示一个或更多的"单词字符",那么这个正则表达式就应该是"\\w+"。如果你要插入一个反斜杠,那就得用"\\\\"。不过像换行,跳格之类的还是只用一根反斜杠:"\n\t"。

这里只给你讲一个例子;你应该JDK文档的java.util.regex.Pattern加到收藏夹里,这样就能很容易地找到各种正则表达式的模式了。

逻辑运算符  
XY X 后面跟着 Y 
X|Y X或Y 
(X) 一个"要匹配的组(capturing group)". 以后可以用\i来表示第i个被匹配的组。 

边界匹配符  
^  一行的开始  
$  一行的结尾  
\b  一个单词的边界  
\B  一个非单词的边界  
\G  前一个匹配的结束  


举一个具体一些的例子。下面这些正则表达式都是合法的,而且都能匹配"Rudolph":

Rudolph
[rR]udolph
[rR][aeiou][a-z]ol.*
R.*
数量表示符
"数量表示符(quantifier)"的作用是定义模式应该匹配多少个字符。

Greedy(贪婪的):除非另有表示,否则数量表示符都是greedy的。Greedy的表达式会一直匹配下去,直到匹配不下去为止。(如果你发现表达式匹配的结果与预期的不符),很有可能是因为,你以为表达式会只匹配前面几个字符,而实际上它是greedy的,因此会一直匹配下去。 
Reluctant(勉强的): 用问号表示,它会匹配最少的字符。也称为lazy, minimal matching, non-greedy, 或ungreedy。 
Possessive (占有的):目前只有Java支持(其它语言都不支持)。它更加先进,所以你可能还不太会用。用正则表达式匹配字符串的时候会产生很多中间状态,(一般的匹配引擎会保存这种中间状态,)这样匹配失败的时候就能原路返回了。占有型的表达式不保存这种中间状态,因此也就不会回头重来了。它能防止正则表达式的失控,同时也能提高运行的效率。 
Greedy  Reluctant  Possessive  匹配  
X?  X??  X?+  匹配一个或零个X  
X*  X*?  X*+  匹配零或多个X  
X+  X+?  X++  匹配一个或多个X  
X{n}  X{n}?  X{n}+  匹配正好n个X  
X{n,}  X{n,}?  X{n,}+  匹配至少n个X  
X{n,m}  X{n,m}?  X{n,m}+  匹配至少n个,至多m个X  

再提醒一下,要想让表达式照你的意思去运行,你应该用括号把'X'括起来。比方说:

abc+
似乎这个表达式能匹配一个或若干个'abc',但是如果你真的用它去匹配'abcabcabc'的话,实际上只会找到三个字符。因为这个表达式的意思是'ab'后边跟着一个或多个'c'。要想匹配一个或多个完整的'abc',你应该这样:

(abc)+
正则表达式能轻而易举地把你给耍了;这是一种建立在Java之上的新语言。

CharSequence
JDK 1.4定义了一个新的接口,叫CharSequence。它提供了String和StringBuffer这两个类的字符序列的抽象:

interface CharSequence {
  charAt(int i);
  length();
  subSequence(int start, int end);
  toString();
}
为了实现这个新的CharSequence接口,String,StringBuffer以及CharBuffer都作了修改。很多正则表达式的操作都要拿CharSequence作参数。

Pattern和Matcher
先给一个例子。下面这段程序可以测试正则表达式是否匹配字符串。第一个参数是要匹配的字符串,后面是正则表达式。正则表达式可以有多个。在Unix/Linux环境下,命令行下的正则表达式还必须用引号。

当你创建正则表达式时,可以用这个程序来判断它是不是会按照你的要求工作。

//: c12:TestRegularExpression.java
// Allows you to easly try out regular expressions.
// {Args: abcabcabcdefabc "abc+" "(abc)+" "(abc){2,}" }
import java.util.regex.*;
public class TestRegularExpression {
  public static void main(String[] args) {
    if(args.length < 2) {
      System.out.println("Usage:\n" +
        "java TestRegularExpression " +
        "characterSequence regularExpression+");
      System.exit(0);
    }
    System.out.println("Input: \"" + args[0] + "\"");
    for(int i = 1; i < args.length; i++) {
      System.out.println(
        "Regular expression: \"" + args[i] + "\"");
      Pattern p = Pattern.compile(args[i]);
      Matcher m = p.matcher(args[0]);
      while(m.find()) {
        System.out.println("Match \"" + m.group() +
          "\" at positions " +
          m.start() + "-" + (m.end() - 1));
      }
    }
  }
} ///:~
 

Java的正则表达式是由java.util.regex的Pattern和Matcher类实现的。Pattern对象表示经编译的正则表达式。静态的compile( )方法负责将表示正则表达式的字符串编译成Pattern对象。正如上述例程所示的,只要给Pattern的matcher( )方法送一个字符串就能获取一个Matcher对象。此外,Pattern还有一个能快速判断能否在input里面找到regex的(注意,原文有误,漏了方法名)

static boolean matches( regex,  input)
以及能返回String数组的split( )方法,它能用regex把字符串分割开来。

只要给Pattern.matcher( )方法传一个字符串就能获得Matcher对象了。接下来就能用Matcher的方法来查询匹配的结果了。

boolean matches()
boolean lookingAt()
boolean find()
boolean find(int start)
matches( )的前提是Pattern匹配整个字符串,而lookingAt( )的意思是Pattern匹配字符串的开头。 

find( )
Matcher.find( )的功能是发现CharSequence里的,与pattern相匹配的多个字符序列。例如:

//: c12:FindDemo.java
import java.util.regex.*;
import com.bruceeckel.simpletest.*;
import java.util.*;
public class FindDemo {
  private static Test monitor = new Test();
  public static void main(String[] args) {
    Matcher m = Pattern.compile("\\w+")
      .matcher("Evening is full of the linnet's wings");
    while(m.find())
      System.out.println(m.group());
    int i = 0;
    while(m.find(i)) {
      System.out.print(m.group() + " ");
      i++;
    }
    monitor.expect(new String[] {
      "Evening",
      "is",
      "full",
      "of",
      "the",
      "linnet",
      "s",
      "wings",
      "Evening vening ening ning ing ng g is is s full " +
      "full ull ll l of of f the the he e linnet linnet " +
      "innet nnet net et t s s wings wings ings ngs gs s "
    });
  }
} ///:~
 

"\\w+"的意思是"一个或多个单词字符",因此它会将字符串直接分解成单词。find( )像一个迭代器,从头到尾扫描一遍字符串。第二个find( )是带int参数的,正如你所看到的,它会告诉方法从哪里开始找——即从参数位置开始查找。

Groups
Group是指里用括号括起来的,能被后面的表达式调用的正则表达式。Group 0 表示整个表达式,group 1表示第一个被括起来的group,以此类推。所以;

A(B(C))D
里面有三个group:group 0是ABCD, group 1是BC,group 2是C。

你可以用下述Matcher方法来使用group:

public int groupCount( )返回matcher对象中的group的数目。不包括group0。

public String group( ) 返回上次匹配操作(比方说find( ))的group 0(整个匹配)

public String group(int i)返回上次匹配操作的某个group。如果匹配成功,但是没能找到group,则返回null。

public int start(int group)返回上次匹配所找到的,group的开始位置。

public int end(int group)返回上次匹配所找到的,group的结束位置,最后一个字符的下标加一。

下面我们举一些group的例子:

//: c12:Groups.java
import java.util.regex.*;
import com.bruceeckel.simpletest.*;
public class Groups {
  private static Test monitor = new Test();
  static public final String poem =
    "Twas brillig, and the slithy toves\n" +
    "Did gyre and gimble in the wabe.\n" +
    "All mimsy were the borogoves,\n" +
    "And the mome raths outgrabe.\n\n" +
    "Beware the Jabberwock, my son,\n" +
    "The jaws that bite, the claws that catch.\n" +
    "Beware the Jubjub bird, and shun\n" +
    "The frumious Bandersnatch.";
  public static void main(String[] args) {
    Matcher m =
      Pattern.compile("(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$")
        .matcher(poem);
    while(m.find()) {
      for(int j = 0; j <= m.groupCount(); j++)
        System.out.print("[" + m.group(j) + "]");
      System.out.println();
    }
    monitor.expect(new String[]{
      "[the slithy toves]" +
      "[the][slithy toves][slithy][toves]",
      "[in the wabe.][in][the wabe.][the][wabe.]",
      "[were the borogoves,]" +
      "[were][the borogoves,][the][borogoves,]",
      "[mome raths outgrabe.]" +
      "[mome][raths outgrabe.][raths][outgrabe.]",
      "[Jabberwock, my son,]" +
      "[Jabberwock,][my son,][my][son,]",
      "[claws that catch.]" +
      "[claws][that catch.][that][catch.]",
      "[bird, and shun][bird,][and shun][and][shun]",
      "[The frumious Bandersnatch.][The]" +
      "[frumious Bandersnatch.][frumious][Bandersnatch.]"
    });
  }
} ///:~
 

这首诗是Through the Looking Glass的,Lewis Carroll的"Jabberwocky"的第一部分。可以看到这个正则表达式里有很多用括号括起来的group,它是由任意多个连续的非空字符('\ S+')和任意多个连续的空格字符('\s+')所组成的,其最终目的是要捕获每行的最后三个单词;'$'表示一行的结尾。但是'$'通常表示整个字符串的结尾,所以这里要明确地告诉正则表达式注意换行符。这一点是由'(?m)'标志完成的(模式标志会过一会讲解)。

start( )和end( )
如果匹配成功,start( )会返回此次匹配的开始位置,end( )会返回此次匹配的结束位置,即最后一个字符的下标加一。如果之前的匹配不成功(或者没匹配),那么无论是调用start( )还是end( ),都会引发一个IllegalStateException。下面这段程序还演示了matches( )和lookingAt( ):

//: c12:StartEnd.java
import java.util.regex.*;
import com.bruceeckel.simpletest.*;
public class StartEnd {
  private static Test monitor = new Test();
  public static void main(String[] args) {
    String[] input = new String[] {
      "Java has regular expressions in 1.4",
      "regular expressions now expressing in Java",
      "Java represses oracular expressions"
    };
    Pattern
      p1 = Pattern.compile("re\\w*"),
      p2 = Pattern.compile("Java.*");
    for(int i = 0; i < input.length; i++) {
      System.out.println("input " + i + ": " + input[i]);
      Matcher
        m1 = p1.matcher(input[i]),
        m2 = p2.matcher(input[i]);
      while(m1.find())
        System.out.println("m1.find() '" + m1.group() +
          "' start = "+ m1.start() + " end = " + m1.end());
      while(m2.find())
        System.out.println("m2.find() '" + m2.group() +
          "' start = "+ m2.start() + " end = " + m2.end());
      if(m1.lookingAt()) // No reset() necessary
        System.out.println("m1.lookingAt() start = "
          + m1.start() + " end = " + m1.end());
      if(m2.lookingAt())
        System.out.println("m2.lookingAt() start = "
          + m2.start() + " end = " + m2.end());
      if(m1.matches()) // No reset() necessary
        System.out.println("m1.matches() start = "
          + m1.start() + " end = " + m1.end());
      if(m2.matches())
        System.out.println("m2.matches() start = "
          + m2.start() + " end = " + m2.end());
    }
    monitor.expect(new String[] {
      "input 0: Java has regular expressions in 1.4",
      "m1.find() 'regular' start = 9 end = 16",
      "m1.find() 'ressions' start = 20 end = 28",
      "m2.find() 'Java has regular expressions in 1.4'" +
      " start = 0 end = 35",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -