- 浏览: 1637579 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (405)
- C/C++ (16)
- Linux (60)
- Algorithm (41)
- ACM (8)
- Ruby (39)
- Ruby on Rails (6)
- FP (2)
- Java SE (39)
- Java EE (6)
- Spring (11)
- Hibernate (1)
- Struts (1)
- Ajax (5)
- php (2)
- Data/Web Mining (20)
- Search Engine (19)
- NLP (2)
- Machine Learning (23)
- R (0)
- Database (10)
- Data Structure (6)
- Design Pattern (16)
- Hadoop (2)
- Browser (0)
- Firefox plugin/XPCOM (8)
- Eclise development (5)
- Architecture (1)
- Server (1)
- Cache (6)
- Code Generation (3)
- Open Source Tool (5)
- Develope Tools (5)
- 读书笔记 (7)
- 备忘 (4)
- 情感 (4)
- Others (20)
- python (0)
最新评论
-
532870393:
请问下,这本书是基于Hadoop1还是Hadoop2?
Hadoop in Action简单笔记(一) -
dongbiying:
不懂呀。。
十大常用数据结构 -
bing_it:
...
使用Spring MVC HandlerExceptionResolver处理异常 -
一别梦心:
按照上面的执行,文件确实是更新了,但是还是找不到kernel, ...
virtualbox 4.08安装虚机Ubuntu11.04增强功能失败解决方法 -
dsjt:
楼主spring 什么版本,我的3.1 ,xml中配置 < ...
使用Spring MVC HandlerExceptionResolver处理异常
正则表达式在处理文本方面用处非常大,最早像在Perl和awk语言中,提供了这种机制,Java在Java 2中也增加了正则表达式这个包java.util.regex。这个包为用户使用正则表达式,提供了易用而全面的支持。我的研究方向是web挖掘。从网页中提取内容,处理文本,当然需要正则表达式这个强大的工具了。
一、首先我们看一下怎么使用正则表达式的一个例子:
A Matcher examines the results of applying a pattern.
我们希望从这句话中找到所有开头为a的单词。
当然这只是一个简单的例子,你可以使用String提供的split方法,得到单词数组,然后
遍历各个单词看是否是否开头为a
我们现在看看怎么使用正则表达式来处理这个问题:
从这个例子我们可以看到正则表达式涉及到的两个类Matcher和Pattern,我们以后会专门讨论着连个类。现在主要看看使用正则表达式的流程:
首先使用 Pattern的一个静态的方法compile来创建Pattern对象,
然后调用Pattern的方法matcher
得到了Matcher对象,Matcher对象保存了许多匹配信息,然后可以通过find()方法
查找匹配的部分,如果有匹配的部分,返回真,使用m.group方法得到匹配的各组值,
否则find返回false.
当然这只是一般的过程,还有许多更细的方法,在以后会陆续的总结,下面我们看一下
这个就是一个正则表达式,b,w,*都是正则表达式的meta character原字符,
\b表示单词的边界,w表示任意的可构成单词的字母数字,*表示前面的字母(当然可以
是更复杂的组之类的了东东)重复0次或0次以上,a当然还是a了。所以这个regex就
匹配单词开头为a的单词了。
二、下面总结一下基本的正则表达式的meta character以及它们含义:
. 匹配任意一个字符 $ 匹配一行的结尾 ^ 匹配一行的开头(在[]里面表示否定)
{} 定义了一个范围 [] 定义了一个字符类 () 定义了一个组
*前面出现0次以上 + 前面匹配一次以上 ?前面出现0次或一次
\ 后面的字符不会看作metacharacter \w 字母数字下划线 \W 非字母数字下划线
\d 单个数字 \D单个非数字 | 或,二者之一 &&与操作符 \b单词边界
下面看看几个简单的例子:
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
三、java.util.regex提供的操作接口:
java.util.regex包提供了操作正则表达式的模型,整个模型优雅而简洁,只有三个类:Pattern、Matcher和
PatternSyntaxException。下面将要总结他们提供的方法,以及如何灵活应用来处理文本。
我们还是从Pattern的静态工厂方法来扩展吧:
将给定的正则表达式编译到模式中,并创建Pattern对象,这个方法通常是操作正则表达式的第一步,从前面那个例子
我们也可以看到整个的流程。
在看看一个重载的compile方法:
将给定的正则表达式编译到具有给定标志的模式中。 这个方法参数flags提供了一些特殊的选项来用于特殊的处理,
我们下面看看可使用的选项:
UNIX_LINES:这个主要处理UNIX和其他的操作系统在行结束符不一样的问题,UNIX使用\n代表一行的终止,而Windows
则使用了\r\n,\n,\r,\u2028或者\u0085作为一行的结束符。
CASE_INSENSITIVE:当我们在匹配的时候要忽略字符大小写时
COMMENTS:允许我们在正则表达式中使用注释,例如
MULTILINE:表明要输入多行,他们有自己的终止字符。
如果你的输入的字符串是:This is a sentence.\n So is this..
这样我们匹配的字符时This中的T和So中的S,如果不使用MULTILINE,则只会匹配T
DOTALL:使用这个选项之后metacharacter .就可以包括一行的终止字符了,如果没有这个选项,
一行的终止字符,并不会考虑在字符串之内的。
使用这个选项会降低效率
如果我们输入的是Test\n,则匹配的字符是5个。
UNICODE_CASE:处理UNICODE字符集,使用这个选项会降低效率
CANON_EQ:一个字符的实际存储形式是经过编码后的数字,使用CANON_EQ选项就可以匹配一个字母在各种编码了。
例如a可以匹配+00E0和U+0061U+0300
使用这个选项会降低效率
我们可以组合以上选项,只要使用|,进行按位或操作即可
我们还要注意点的时Java对转译字符\的处理,例如我们要匹配一个数字:
我们不能使用:
而是:
另外如果regex本身形式是错误的,compile方法会抛出java.util.regex.PatternSyntaxException异常。
下面我们总结一下public Matcher matcher(CharSequence input)方法:
当我们使用compile操作,创建了Pattern对象之后,我们就可以使用Pattern对象的matcher操作,生成
matcher对象了,Matcher对象包含了许多对匹配结果集的操作,我们在总结Matcher对象的时候再说。另外
顺便提一下参数CharSequence,CharBuffer, Segment, String, StringBuffer, StringBuilder 都实现了
这个接口,所以参数可以是这些中的任一种类型了。
下面我们看看:
这个方法返回了我们前面可以设置的并且已经设置的flags选项,我们通过按位与来判断是否设置了某个选项:
看看一个简化过程的方法:
这个方法实际上是:
过程的一个简化,我们在后面总结Matcher中的matches方法之后就会理解这个了。
想必我们经常使用把字符串提取出token变成字符串数组的String中的split方法吧,下面我们看看
类似的一个方法:
public String[] split(CharSequence input)
这个方法提供了强大的功能,因为它可以使用正则表达式来作为token的分割:
split的一个重载的版本:
它指定了划分的组数,有以下三种情况:
limit==0
这时候和没有limit参数的那个split效果一样
limit>0
如果你仅仅对前limit个感兴趣,你可以使用limit:
limit<0
会尽可能的划分所有的组,即使分割符后面是个空字符,也要单独生成一个token:""
下次再总结Matcher类,和正则表达式的一些高级部分
很好 正要学 这个很好。。。
http://fuliang.iteye.com/blog/175035
一、首先我们看一下怎么使用正则表达式的一个例子:
A Matcher examines the results of applying a pattern.
我们希望从这句话中找到所有开头为a的单词。
当然这只是一个简单的例子,你可以使用String提供的split方法,得到单词数组,然后
遍历各个单词看是否是否开头为a
我们现在看看怎么使用正则表达式来处理这个问题:
import java.util.regex.*; public class FindA{ public static void main(String args[]) throws Exception{ String candidate = "A Matcher examines the results of applying a pattern."; String regex = "\\ba\\w*\\b"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(candidate); String val = null; System.out.println("INPUT: " + candidate); System.out.println("REGEX: " + regex +"\r\n"); while (m.find()){ val = m.group(); System.out.println("MATCH: " + val); } if (val == null) { System.out.println("NO MATCHES: "); } } }
从这个例子我们可以看到正则表达式涉及到的两个类Matcher和Pattern,我们以后会专门讨论着连个类。现在主要看看使用正则表达式的流程:
首先使用 Pattern的一个静态的方法compile来创建Pattern对象,
Pattern p = Pattern.compile(regex);
然后调用Pattern的方法matcher
Matcher m = p.matcher(candidate);
得到了Matcher对象,Matcher对象保存了许多匹配信息,然后可以通过find()方法
查找匹配的部分,如果有匹配的部分,返回真,使用m.group方法得到匹配的各组值,
否则find返回false.
当然这只是一般的过程,还有许多更细的方法,在以后会陆续的总结,下面我们看一下
String regex = "\\ba\\w*\\b";
这个就是一个正则表达式,b,w,*都是正则表达式的meta character原字符,
\b表示单词的边界,w表示任意的可构成单词的字母数字,*表示前面的字母(当然可以
是更复杂的组之类的了东东)重复0次或0次以上,a当然还是a了。所以这个regex就
匹配单词开头为a的单词了。
二、下面总结一下基本的正则表达式的meta character以及它们含义:
. 匹配任意一个字符 $ 匹配一行的结尾 ^ 匹配一行的开头(在[]里面表示否定)
{} 定义了一个范围 [] 定义了一个字符类 () 定义了一个组
*前面出现0次以上 + 前面匹配一次以上 ?前面出现0次或一次
\ 后面的字符不会看作metacharacter \w 字母数字下划线 \W 非字母数字下划线
\d 单个数字 \D单个非数字 | 或,二者之一 &&与操作符 \b单词边界
下面看看几个简单的例子:
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
三、java.util.regex提供的操作接口:
java.util.regex包提供了操作正则表达式的模型,整个模型优雅而简洁,只有三个类:Pattern、Matcher和
PatternSyntaxException。下面将要总结他们提供的方法,以及如何灵活应用来处理文本。
我们还是从Pattern的静态工厂方法来扩展吧:
static Pattern compile(String regex)
将给定的正则表达式编译到模式中,并创建Pattern对象,这个方法通常是操作正则表达式的第一步,从前面那个例子
我们也可以看到整个的流程。
在看看一个重载的compile方法:
static Pattern compile(String regex, int flags)
将给定的正则表达式编译到具有给定标志的模式中。 这个方法参数flags提供了一些特殊的选项来用于特殊的处理,
我们下面看看可使用的选项:
UNIX_LINES:这个主要处理UNIX和其他的操作系统在行结束符不一样的问题,UNIX使用\n代表一行的终止,而Windows
则使用了\r\n,\n,\r,\u2028或者\u0085作为一行的结束符。
CASE_INSENSITIVE:当我们在匹配的时候要忽略字符大小写时
COMMENTS:允许我们在正则表达式中使用注释,例如
Pattern p =Pattern.compile("A #matches uppercase US-ASCII char code 65",Pattern.COMMENTS);
MULTILINE:表明要输入多行,他们有自己的终止字符。
Pattern p = Pattern.compile("^", Pattern.MULTILINE);
如果你的输入的字符串是:This is a sentence.\n So is this..
这样我们匹配的字符时This中的T和So中的S,如果不使用MULTILINE,则只会匹配T
DOTALL:使用这个选项之后metacharacter .就可以包括一行的终止字符了,如果没有这个选项,
一行的终止字符,并不会考虑在字符串之内的。
使用这个选项会降低效率
Pattern p = Pattern.compile(".", Pattern.DOTALL);
如果我们输入的是Test\n,则匹配的字符是5个。
UNICODE_CASE:处理UNICODE字符集,使用这个选项会降低效率
CANON_EQ:一个字符的实际存储形式是经过编码后的数字,使用CANON_EQ选项就可以匹配一个字母在各种编码了。
例如a可以匹配+00E0和U+0061U+0300
使用这个选项会降低效率
我们可以组合以上选项,只要使用|,进行按位或操作即可
Pattern p = Pattern.compile("t # a compound flag example",Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE| Pattern.COMMENT);
我们还要注意点的时Java对转译字符\的处理,例如我们要匹配一个数字:
我们不能使用:
Pattern p = Pattern.compile("\d");
而是:
Pattern p = Pattern.compile("\\d");
另外如果regex本身形式是错误的,compile方法会抛出java.util.regex.PatternSyntaxException异常。
下面我们总结一下public Matcher matcher(CharSequence input)方法:
当我们使用compile操作,创建了Pattern对象之后,我们就可以使用Pattern对象的matcher操作,生成
matcher对象了,Matcher对象包含了许多对匹配结果集的操作,我们在总结Matcher对象的时候再说。另外
顺便提一下参数CharSequence,CharBuffer, Segment, String, StringBuffer, StringBuilder 都实现了
这个接口,所以参数可以是这些中的任一种类型了。
下面我们看看:
public int flags()
这个方法返回了我们前面可以设置的并且已经设置的flags选项,我们通过按位与来判断是否设置了某个选项:
int flgs = myPattern.flags(); boolean isUsingCommentFlag =( Pattern.COMMENTS == (Pattern.COMMENTS & flgs)) ;
看看一个简化过程的方法:
public static boolean matches (String regex,CharSequence input)
这个方法实际上是:
Pattern p = Pattern.compile(regex); Matcher m = p.matcher(candidate); m.matches()
过程的一个简化,我们在后面总结Matcher中的matches方法之后就会理解这个了。
想必我们经常使用把字符串提取出token变成字符串数组的String中的split方法吧,下面我们看看
类似的一个方法:
public String[] split(CharSequence input)
这个方法提供了强大的功能,因为它可以使用正则表达式来作为token的分割:
Pattern p = new Pattern.compile(",|and"); String fruits[] = p.split("apple,banana and orange");
split的一个重载的版本:
public String[] split(CharSequence input, int limit)
它指定了划分的组数,有以下三种情况:
limit==0
这时候和没有limit参数的那个split效果一样
limit>0
如果你仅仅对前limit个感兴趣,你可以使用limit:
String[] tmp = pattern.split("Hello, Dolly, You, Are, My, Favorite",3); //tmp[0] is "Hello", // tmp[1] is "Dolly"; //tmp[2] is "You, Are, My, Favorite";
limit<0
会尽可能的划分所有的组,即使分割符后面是个空字符,也要单独生成一个token:""
Pattern p = Pattern.compile(","); String temp[] = p.split("Hello,Dolly,", -1); //temp[]={"Hello","Dolly",""}
下次再总结Matcher类,和正则表达式的一些高级部分
评论
10 楼
springdata
2014-08-04
java 正则代码教程下载地址:http://www.zuidaima.com/share/k%E6%AD%A3%E5%88%99-p1-s1.htm
9 楼
beritha
2011-10-19
看了这个,明白了好多,谢谢
8 楼
lizhensan
2011-07-06
学了。。。。讲的太好了。
7 楼
camus518
2010-11-09
6 楼
camus518
2010-11-09
whicky 写道
学习了~~~
很好 正要学 这个很好。。。
5 楼
truth315
2010-04-29
Pattern p = new Pattern.compile(",|and");
楼主有一点小问题哦 ,Pattern工厂方法,注意实例化对象的惯性哦
楼主有一点小问题哦 ,Pattern工厂方法,注意实例化对象的惯性哦
4 楼
fuliang
2010-04-14
spiritfrog 写道
期待续。。。
http://fuliang.iteye.com/blog/175035
3 楼
spiritfrog
2010-04-08
期待续。。。
2 楼
whicky
2009-09-16
学习了~~~
1 楼
guyikun
2008-03-30
呵呵
看看,也学学~
看看,也学学~
发表评论
-
Builder模式遇到继承
2013-10-13 13:48 0interface Self<T extends ... -
Builder模式遇到集成
2013-10-13 13:47 0package com.qunar.qss.business. ... -
JVM调优Step by Step
2012-02-02 17:38 0现代的JVM能够适应于各种应用和领域,每个应用和领域的使用 ... -
commons-lang StringUtils#split的坑
2011-12-31 10:11 3113今天用StringUtils#split,陷入了前两个坑。需求 ... -
使用scala.sys.process包和系统交互
2011-07-19 00:00 6440在Java中我们可以使用Runtime.getRuntime( ... -
HttpClient Json请求工具
2011-05-05 18:32 17803发送Json请求,结果返回Json. public sta ... -
利用Java反射实现通用的Excel报表
2011-04-12 16:00 1983最近有很多客户报表需要提供客户下载,需要生成一个Excel的格 ... -
深入异常处理
2011-03-31 20:46 1773异常处理是写一个健壮 ... -
Java序列化注意一些点
2011-03-12 21:04 18131.序列化ID的问题: 标示了版本号,版本号一致才能反序列化成 ... -
Java动态代理
2010-09-24 00:34 4401Java提供了动态代理,可以完成AOP和装饰模式的功能,主要的 ... -
Java Timestamp是和ExtJS的timestamp不兼容
2010-08-09 20:33 3323Timestamp纳秒级别的,ExtJS的timestamp使 ... -
XML DocumentBuilder#parse(String str)
2010-07-06 15:55 3849DocumentBuilderFactory dbf = ... -
[备忘]String#split/substring的子串会共享原来大的String
2010-03-29 17:18 1450如果每次需要大字符串中的很小的一个字串,可能会引起内存中大量的 ... -
runtime.exec()执行进程block死锁问题
2010-01-18 21:39 5232最近在java代码中使用runtime.exec执行rsync ... -
URL中文问题
2010-01-08 14:46 10476最近使用HttpClient,和Java的java.net.U ... -
A TaskExecutor Impl
2009-12-07 11:33 1584import java.util.ArrayList; im ... -
使用XStream把Java对象XML/JSON格式的序列化和反序列化
2009-05-05 11:37 6188试了一下Thoughtworks的XStream,以测试驱动和 ... -
从《编程的未来》这篇文章想到C++和Java语言的爽与不爽
2009-05-01 23:44 3935从编程的未来这篇文 ... -
《Effetive Java》读书笔记二
2009-02-23 14:23 1568第二章 所有对象共有的 ... -
《Effetive Java》读书笔记一
2009-02-19 11:36 2138《Effetive Java》和 《Effective C++ ...
相关推荐
本文写作时,一个包含了用正则表达式进行文本处理的Java规范需求(Specification Request)已经得到认可,你可以期待在JDK的下一版本中看到它。 然而,如果现在就需要使用正则表达式,又该怎么办呢?你可以从Apache...
Java正则表达式Java正则表达式Java正则表达式Java正则表达式
java,正则表达式,详解,java正则表达式,PDF
Java正则表达式 Java 正则表达式 图片版 携带方便,查阅方便!~
JAVA正则表达式应用:任意输入一串字符串 如何输入exit退出程序;从输入的字符串中判断是否包含手机号码 正则表达式可以使用" +86| 86 1 d{10}" 如果包含请将其在控制台打印出来 否则输出不包含字符串 ...
正则表达式之道.doc 正则表达式中的特殊字符.doc Java正则表达式详解.doc 正则表达式.ppt JAVA正则表达式--Pattern和Matcher.doc 例子
java正则表达式详解java正则表达式详解java正则表达式详解java正则表达式详解java正则表达式详解java正则表达式详解java正则表达式详解
java正则表达式验证IP地址
java使用正则表达式进行校验验证,主要使用了Pattern和Matcher类,直接main方法运行就可以,亲测有效
java正则表达式.pdfjava正则表达式.pdfjava正则表达式.pdfjava正则表达式.pdfjava正则表达式.pdf
Java正则表达式介绍和练习Java正则表达式介绍和练习Java正则表达式介绍和练习
Java正则表达式应用总结
java正则表达式 过滤特殊字符的正则表达式
Jva正则表达式Jva正则表达式Jva正则表达式Jva正则表达式Jva正则表达式
正则表达式的使用 java正则表达式的使用示例 java正则表达式
我在一次偶然中发现了位于 java.sun.com 站点上的 Java Tutorial,也在那里看到了关于 Java 的正则表达式教程,感觉它不同于其他的正则表达式教程,文中以大量的匹配实例来进行说明。为了能让 Java 学习者能更好地...
java正则表达式使用例子,代码是Android的
Java正则表达式详解.pdf Java正则表达式详解.pdf
正则表达式匹配工具很好很强大 放心使用 内附各种经典正则匹配公式
java正则表达式详细全面讲解描述