代码改变世界

Java正则表达式

2017-02-09 14:30  taozsay  阅读(110)  评论(0编辑  收藏  举报

Java提供了java.util.regex包的模式正则表达式匹配。 Java正则表达式是非常相似的Perl编程语言,很容易学习。

正则表达式是一个字符的特殊序列,可以帮助您匹配或查找其他字符串或字符串集,使用的模式举行了专门的语法。它们可以被用于搜索,编辑或处理文本和数据。

在java.util.regex包主要包括以下三类:

  • Pattern 类: Pattern对象是一个正则表达式的编译表示。 Pattern类不提供公共构造函数。要创建一个模式,必须首先调用其公共静态编译的方法之一,这将返回一个Pattern对象。这些方法接受一个正则表达式作为第一个参数。

  • Matcher 类: Matcher对象是解释模式,并执行对输入字符串匹配操作的引擎。像Pattern类,匹配器定义没有公共的构造函数。通过调用一个Pattern对象的匹配方法获得一个Matcher对象。

  • PatternSyntaxException: PatternSyntaxException对象是一个未经检查的异常,表明正则表达式模式中的语法错误.

捕获组:

捕获组是一种方法处理多种字符作为一个单一的单元。他们被放置到一组括号内分组字符创建。例如,正则表达式(dog)创建一个包含字母"d", "o" 和  "g" 的一个组。 .

捕获组是由左至右计数的左括号的编号。例如,表达式((A)(B(C)))有四个这样的组:

  • ((A)(B(C)))

  • (A)

  • (B(C))

  • (C)

要找出有多少组出现在表达式,调用一个匹配对象的groupCount方法。groupCount方法返回一个int表示目前在匹配器模式的捕获组数.

还有一个特别的组,组0,它始终代表整个表达式。此组中不包括所报告groupCount的总和。

例子:

下面的例子说明如何找到从给定的字母数字字符串,一个数字串:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    public static void main( String args[] ){

      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      } else {
         System.out.println("NO MATCH");
      }
   }
}

这将产生以下结果:

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

正则表达式语法

这里的表中列出了所有的正则表达式元字符,并可在Java中的语法:

子表达式匹配
^ 匹配一行的开始.
$ 匹配一行的结尾.
. 匹配除换行符外的任何单个字符。使用m选项允许它匹配换行符.
[...] 匹配括号中的任何单个字符.
[^...] 匹配非括号中的任何单个字符
A 整个字符串的开头
z 整个字符串的结尾
 除了允许的最后行结束整个字符串的结尾.
re* 匹配0个或多个前面的表达式.
re+ 匹配1个或更多的前面的表达式
re? 匹配0或1发生在前面的表达式
re{ n} 精确匹配n个前面的表达式的数量.
re{ n,} 匹配n个或多个前面的表达式.
re{ n, m} 匹配至少n和前面表达式出现m次.
a| b 匹配A或B。
(re) 组正则表达式并记住匹配的文本。
(?: re) 组正则表达式不记忆匹配的文本。
(?> re) 匹配的独立模式,省去反向追踪.
w 匹配单词字符.
W 匹配非单词字符.
s 匹配空白。相当于 [ f].
S 匹配一个非空白.
d 匹配数字。相当于 [0-9].
D 匹配非数字.
A 匹配开始的字符串.
 匹配字符串的结尾。如果一个换行符存在,它只是在换行前.
z 字符串的匹配结束.
G 最后一次匹配结束匹配点.
  向后引用捕获组号"n"
 匹配单词边界之外时,括号内。匹配退格(0X08)括号内.
B 匹配非单词边界.
, , etc. 匹配换行符,回车符,制表符等。
Q 转义(引用)的所有字符到 E
E 引用结束带Q开始

Matcher 类的方法:

这里是一个有用的实例方法的列表:

index方法:

索引方法提供了精确显示的地方找到匹配输入字符串有用的索引值:

SN方法和描述
1 public int start() 
返回前一个匹配的初始索引.
2 public int start(int group)
返回序列的以前匹配操作期间由给定组捕获的起始索引.
3 public int end()
返回匹配的最后一个字符之后的偏移.
4 public int end(int group)
返回在以前的匹配操作期间由给定组所捕获子序列的最后一个字符之后的偏移.

Study方法:

研究方法的检讨输入字符串,并返回一个Boolean值,指示模式是否发现:

SN方法和描述
1 public boolean lookingAt() 
尝试以匹配输入序列,起始于该区域的开始,针对模式.
2 public boolean find() 
试图找到输入序列与该模式匹配的下一个子序列.
3 public boolean find(int start
重置此匹配器,然后尝试找到输入序列与该模式匹配的下一个子序列,从指定的索引处.
4 public boolean matches() 
尝试对整个区域匹配的模式.

Replace方法:

替代的方法是在输入字符串替换文本有用的方法:

SN方法和描述
1 public Matcher appendReplacement(StringBuffer sb, String replacement)
实现了一个非末端追加和替换步骤.
2 public StringBuffer appendTail(StringBuffer sb)
实现了终端追加和替换步骤.
3 public String replaceAll(String replacement) 
替换输入序列中与给定替换字符串匹配的模式的每个子序列.
4 public String replaceFirst(String replacement)
替换输入序列中与给定替换字符串匹配的模式的第一序列.
5 public static String quoteReplacement(String s)
返回一个文本替换字符串指定的字符串。这种方法产生一个String,它将会作为一个文本替换s在Matcher类的appendReplacement方法.

start 和 end 方法:

以下是计算的次数的单词 "cats"出现在输入字符串中的示例: 

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    private static final String REGEX = "\bcat\b";
    private static final String INPUT =
                                    "cat cat cat cattie cat";

    public static void main( String args[] ){
       Pattern p = Pattern.compile(REGEX);
       Matcher m = p.matcher(INPUT); // get a matcher object
       int count = 0;

       while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

这将产生以下结果:

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

可以看到,这个例子使用单词边界,保证了字母 "c" "a" "t" 不能仅仅停留在一个较长的单词子串。它还提供了有关在何处输入字符串中匹配发生一些有用的信息。

start方法将返回以前匹配操作期间由给定组捕获的子序列的起始索引和结束返回匹配的最后一个字符的索引加一。

matches 和 lookAt 方法:

匹配和寻找方法都试图用模式匹配的输入序列。差别是:匹配要求整个输入序列进行匹配,而寻找没有。

这两种方法总是从输入字符串的开始位置。下面是示例说明它的功能:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    private static final String REGEX = "foo";
    private static final String INPUT = "fooooooooooooooooo";
    private static Pattern pattern;
    private static Matcher matcher;

    public static void main( String args[] ){
       pattern = Pattern.compile(REGEX);
       matcher = pattern.matcher(INPUT);

       System.out.println("Current REGEX is: "+REGEX);
       System.out.println("Current INPUT is: "+INPUT);

       System.out.println("lookingAt(): "+matcher.lookingAt());
       System.out.println("matches(): "+matcher.matches());
   }
}

这将产生以下结果:

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

replaceFirst 和 replaceAll 方法:

replaceFirst和replaceAll方法替换匹配给定的正则表达式的文本。正如其名称表明,replaceFirst替换第一次出现,而replaceAll替换所有出现。

下面是示例说明它的功能:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    private static String REGEX = "dog";
    private static String INPUT = "The dog says meow. " +
                                    "All dogs say meow.";
    private static String REPLACE = "cat";

    public static void main(String[] args) {
       Pattern p = Pattern.compile(REGEX);
       // get a matcher object
       Matcher m = p.matcher(INPUT); 
       INPUT = m.replaceAll(REPLACE);
       System.out.println(INPUT);
   }
}

这将产生以下结果:

The cat says meow. All cats say meow.

appendReplacement 和 appendTail 方法:

Matcher 类还提供appendReplacement和appendTail方法文本替换。

下面是示例说明它的功能:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      // get a matcher object
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()){
         m.appendReplacement(sb,REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

这将产生以下结果:

-foo-foo-foo-

PatternSyntaxException 类方法:

PatternSyntaxException是一个未经检查的异常,表明正则表达式模式中的语法错误。PatternSyntaxException类提供以下方法来帮助确定什么地方出了错:

 

SN方法和描述
1 public String getDescription()
检索该错误的描述.
2 public int getIndex() 
检索错误索引.
3 public String getPattern() 
检索错误的正则表达式模式.
4 public String getMessage() 
返回包含语法错误的描述和它的索引,错误的正则表达式模式的多行字符串,并且在该模式内的错误索引的可视指示.