码迷,mamicode.com
首页 > 编程语言 > 详细

Java:正则表达式

时间:2016-01-08 22:05:29      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:

正则表达式语法:

技术分享
语法                             解释

字符:
c                                            |字符c
\unnnn, \xnn,\0n,\0nn,\0nnn    |具有给定十六进制或十进制的码元
\t,\n,\r,\f,\a,\e                         |控制符:制表符、换行符、回车符、换页符、警告符、逃逸符
\cc                                          |与字符c相关的控制符

字符类:
[C1C2...]                                 |任何由C1,C2...表示的字符,其中Ci可以是多个字符、字符范围是C1-C2或字符类
[^......]                                    |字符类的补集
[...&&..]                                    |两个字符集的交集

预定义字符类:
除了行终止符之外所有的字符(在DOTALL标志被设置时,则表示所有字符)
\d                                           |一个数字[0-9]
\D                                           |一个非数字[0-9]
\s                                            |一个空白字符[\t\n\t\f\x0B]
\S                                           |一个非空白字符
\w                                           |一个词语字符[a-zA-Z0-9]
\W                                          |一个非词语字符
\p{name}                                |一个命名字符类
\P{name}                                |一个命名字符类的补集

边界匹配符:
^$                                          |输入的开头和结尾
\b                                           |一个词语边界
\B                                           |一个非词语字符
\A                                           |输入的开头
\z                                           |输入的结尾
\Z                                           |除了终止符之外的输入结尾
\G                                           |前一个匹配的结尾

量词:
X?                                           |可选的X
X*                                           |X重复0或多次
X+                                           |X重复1或多次
X{n}X{n,}X{n,m}                      |X重复n次,至少n次,在n到m次之间

量词后缀:
?                                             |将默认(贪婪)匹配转变为勉强匹配
+                                             |将默认(贪婪)匹配转变为占有匹配

集合操作:
XY                                           |任何X中的字符串,后面跟随任何Y中的字符串
X|Y                                          |任何X或Y的字符串

群组:
(X)                                          |捕获将X作为群组匹配的字符串
\n                                            |第n个群组的匹配

转义:
\c                                            |字符c(必须是不在字母表中的字符)
\Q.....\E                                   |逐字的引用...
(?...)                                        |特殊结构
View Code

1.设计一个简单的表达式来匹配任何电话号码数字可能是比较复杂的事情,原因在于电话号码格式有很多种情况。所有必须选择一个比较有效的模式。比如:(212) 555-1212, 212-555-1212和212 555 1212,某些人会认为它们都是等价的。

  首先让我们构成一个正则表达式。为简单起见,先构成一个正则表达式来识别下面格式的电话号码数字:(nnn)nnn-nnnn。

  第一步,创建一个pattern对象来匹配上面的子字符串。一旦程序运行后,如果需要的话,可以让这个对象一般化。匹配上面格式的正则表达可以这样构成: (\d{3})\s\d{3}-\d{4},其中\d单字符类型用来匹配从0到9的任何数字,另外{3}重复符号,是个简便的记号,用来表示有3个连续的 数字位,也等效于(\d\d\d)。\s也另外一个比较有用的单字符类型,用来匹配空格,比如Space键,tab键和换行符。

  是不是很简单?但是,如果把这个正则表达式的模式用在java程序中,还要做两件事。对java的解释器来说,在反斜线字符(\)前的字符有特殊的 含义。在java中,与regex有关的包,并不都能理解和识别反斜线字符(/),尽管可以试试看。但为避免这一点,即为了让反斜线字符(\)在模式对象 中被完全地传递,应该用双反斜线字符(\\)。此外圆括号在正则表达中两层含义,如果想让它解释为字面上意思(即圆括号),也需要在它前面用双反斜线字符 (\\)。也就是像下面的一样:

  \\(\\d{3}\\)\\s\\d{3}-\\d{4}

  下面的一段代码实现的功能是,从一个文本文件逐行读入,并逐行搜索电话号码数字,一旦找到所匹配的,然后输出在控制台。

技术分享
 1 package perl;
 2 import java.io.*;
 3 import java.util.regex.*;
 4 public class test_number {
 5     public static void main(String[] args) throws IOException{
 6         BufferedReader in;
 7         Pattern pattern=Pattern.compile("\\(\\d{3}\\)\\s\\d{3}-\\d{4}");
 8         in=new BufferedReader(new FileReader("C:/Users/liuzhongfeng/Desktop/文件/java/phone.txt"));
 9         String s;
10         while((s=in.readLine())!=null){            
11             Matcher matcher=pattern.matcher(s);
12             if(matcher.find()){
13                 System.out.println(matcher.group());
14             }
15         }
16         in.close();
17     }
18 }
View Code

结果为:

(121) 525-1111
(000) 545-5555
(000) 545-5555

原文为:
(121) 525-1111
(000) 545-5555
(000)-545-5555
(000) 545-55555
(000)-545-5555

  对于程序中的find()函数,用来匹配搜索与正则表达式相匹配id任何目标字符串,group()方法,用来返回包含了所匹配文本的字符串,应注意的是,上面的代码,仅用在每行只能含有一个匹配的电话号码数字字符串时。可以肯定的说,java的正则表达式包能用在一行含有多个匹配目标时的搜索。这相当漂亮吧! 但是很遗憾的是,这仅是个电话号码匹配器。

  很明显,还有两点可以改进。如果在电话号码的开头,即区位号和本地号码之间可能会有空格。我们也可匹配这些情况,则通过在正则表达式中加入/s?来实现,其中?元字符表示在模式可能有0或1个空格符。

  第二点是,在本地号码位的前三位和后四位数字间有可能是空格符,而不是连字号,更有胜者,或根本就没有分隔符,就是7位数字连在一起。对这几种情况,我们 可以用(-|)?来解决。这个结构的正则表达式就是转换器,它能匹配上面所说的几种情况。在()能含有管道符|时,它能匹配是否含有空格符或连字符,而尾 部的?元字符表示是否根本没有分隔符的情况。最后,区位号也可能没有包含在圆括号内,对此可以简单地在圆括号后附上?元字符,但这不是一个很好的解决方法。因为它也包含了不配对的圆括号,比如" (555" 或 "555)"。相反,我们可以通过另一种转换器来强迫让电话号码是否带有有圆括号:(\(\d{3}\)|\d{3})。如果我们把上面代码中的正则表达 式用这些改进后的来替换的话,上面的代码就成了一个非常有用的电话号码数字匹配器:Pattern pattern =Pattern.compile("(\\(\\d{3}\\)|\\d{3})\\s?\\d{3}(-|)?\\d{4}");

可以确定的是,你可以自己试着进一步改进上面的代码。

2.第二个例子:它是从Friedl的中改编过来的,其功能是检查文本中是否有重复的单词,这在印刷排版中会经常遇到,同样也是个语法检查器的问题。

  匹配单词好几种正则表达式,最可能直接的是\b\w+\b,优点是只需少量的regex元字符。其中/w元字符用来匹配从字母a到u的任何字符。+元字符表示匹配匹配一次或多次字符,/b元字符是用来说明匹配单词的边界,它可以是空格或任何一种不同的标点符号(包括逗号,句号等)。

  圆括号在正则表达式中有几种不同的用法,一个就是能提供组合类型,组合类型用来保存所匹配的结果或部分匹配的结果(以便后面能用到),即使遇到有相同的模 式。在同样的正则表达中,可能(也通常期望)不止有一个组合类型。在第n个组合类型中匹配结果可以通过向后扫描来获取到。向后扫描使得搜索重复的单词非常 简单:\b(\w+)\s+\1\b。向后扫描\1,指的是任何被\w+所匹配的单词。我们的正则表达式因此能匹配这样的,它有一个或多个空格符,后面还跟有一个与此相同的单词。

  最后进一步的修改是让我们的匹配器对大小写敏感。比如,下面的情况:"The the theme of this article is the Java‘s regex package.",这一点在regex中能非常简单地实现,即通过使用在Pattern类中预定义的静态标志CASE_INSENSITIVE。

  pattern pattern=Pattern.compile("\\b(\\w+)\\s+\\1\\b");

  Pattern.CASE_INSENSITIVE();

2、CharSequence

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

    interface CharSequence{

      charAt(int i);

      length();

      subSequence(int start,int end);

      toString();

    }

3、Pattern和Matcher

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

  Java的正则表达式是由java.util.regex的Pattern和Matcher类实现的Pattern对象表示经编译的正则表达式。静态的compile( )方法负责将表示正则表达式的字符串编译成Pattern对象。正如上述例程所示的,只要给Pattern的matcher( )方法送一个字符串就能获取一个Matcher对象。只要给Pattern matcher()方法传一个字符串就能够获得Matcher的方法来查询匹配的结果了。

  boolean matches()

  boolean lookingAt()

  boolean find()

  boolean find(int start)

  matches()的前提是Pattern匹配整个字符串,而lookingAt()的意思是Pattern匹配字符串的开头。对于find()函数,Matcher.find()的功能是发现CharSequence里的,与pattern相匹配的多个字符序列。例如:

Java:正则表达式

标签:

原文地址:http://www.cnblogs.com/liuzhongfeng/p/5114671.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!