JAVA正则表达式 Pattern和Matcher

1.简介:
java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。
它包括两个类:Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表现模式。
Matcher 一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。
首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。
以下我们就分别来看看这两个类:
2.Pattern类:
Pattern的方法如下: static Pattern compile(String regex)
将给定的正则表达式编译并赋予给Pattern类
static Pattern compile(String regex, int flags)
同上,但增加flag参数的指定,可选的flag参数包括:CASE INSENSITIVE,MULTILINE,DOTALL,UNICODE CASE, CANON EQ
int flags()
返回当前Pattern的匹配flag参数.
Matcher matcher(CharSequence input)
生成一个给定命名的Matcher对象
static boolean matches(String regex, CharSequence input)
编译给定的正则表达式并且对输入的字串以该正则表达式为模开展匹配,该方法适合于该正则表达式只会使用一次的情况,也就是只进行一次匹配工作,因为这种情况下并不需要生成一个Matcher实例。
String pattern()
返回该Patter对象所编译的正则表达式。
String[] split(CharSequence input)
将目标字符串按照Pattern里所包含的正则表达式为模进行分割。
String[] split(CharSequence input, int limit)
作用同上,增加参数limit目的在于要指定分割的段数,如将limi设为2,那么目标字符串将根据正则表达式分为割为两段。
一个正则表达式,也就是一串有特定意义的字符,必须首先要编译成为一个Pattern类的实例,这个Pattern对象将会使用matcher()方法来生成一个Matcher实例,接着便可以使用该 Matcher实例以编译的正则表达式为基础对目标字符串进行匹配工作,多个Matcher是可以共用一个Pattern对象的。
现在我们先来看一个简单的例子,再通过分析它来了解怎样生成一个Pattern对象并且编译一个正则表达式,最后根据这个正则表达式将目标字符串进行分割:


代码如下:

import java.util.regex.*;
public class Replacement{
public static void main(String[] args) throws Exception {
// 生成一个Pattern,同时编译一个正则表达式
Pattern p = Pattern.compile("[/]+");
//用Pattern的split()方法把字符串按"/"分割
String[] result = p.split(
"Kevin has seen《LEON》seveal times,because it is a good film."
+"/ 凯文已经看过《这个杀手不太冷》几次了,因为它是一部"
+"好电影。/名词:凯文。");
for (int i=0; i<result.length; i++)
System.out.println(result[i]);
}
}

输出结果为:
Kevin has seen《LEON》seveal times,because it is a good film.
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。
名词:凯文。
很明显,该程序将字符串按"/"进行了分段,我们以下再使用 split(CharSequence input, int limit)方法来指定分段的段数,程序改动为:
tring[] result = p.split("Kevin has seen《LEON》seveal times,because it is a good film./ 凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。",2);
这里面的参数"2"表明将目标语句分为两段。
输出结果则为:
Kevin has seen《LEON》seveal times,because it is a good film.
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。
由上面的例子,我们可以比较出java.util.regex包在构造Pattern对象以及编译指定的正则表达式的实现手法与我们在上一篇中所介绍的Jakarta-ORO 包在完成同样工作时的差别,Jakarta-ORO 包要先构造一个PatternCompiler类对象接着生成一个Pattern对象,再将正则表达式用该PatternCompiler类的compile()方法来将所需的正则表达式编译赋予Pattern类:
PatternCompiler orocom=new Perl5Compiler();
Pattern pattern=orocom.compile("REGULAR EXPRESSIONS");
PatternMatcher matcher=new Perl5Matcher();
但是在java.util.regex包里,我们仅需生成一个Pattern类,直接使用它的compile()方法就可以达到同样的效果:
Pattern p = Pattern.compile("[/]+");
因此似乎java.util.regex的构造法比Jakarta-ORO更为简洁并容易理解。
3.Matcher类:
Matcher方法如下: Matcher appendReplacement(StringBuffer sb, String replacement)
将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里。
StringBuffer appendTail(StringBuffer sb)
将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
int end()
返回当前匹配的子串的最后一个字符在原目标字符串中的索引位置 。
int end(int group)
返回与匹配模式里指定的组相匹配的子串最后一个字符的位置。
boolean find()
尝试在目标字符串里查找下一个匹配子串。
boolean find(int start)
重设Matcher对象,并且尝试在目标字符串里从指定的位置开始查找下一个匹配的子串。
String group()
返回当前查找而获得的与组匹配的所有子串内容
String group(int group)
返回当前查找而获得的与指定的组匹配的子串内容
int groupCount()
返回当前查找所获得的匹配组的数量。
boolean lookingAt()
检测目标字符串是否以匹配的子串起始。
boolean matches()
尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值。
Pattern pattern()
返回该Matcher对象的现有匹配模式,也就是对应的Pattern 对象。
String replaceAll(String replacement)
将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串。
String replaceFirst(String replacement)
将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串。
Matcher reset()
重设该Matcher对象。
Matcher reset(CharSequence input)
重设该Matcher对象并且指定一个新的目标字符串。
int start()
返回当前查找所获子串的开始字符在原目标字符串中的位置。
int start(int group)
返回当前查找所获得的和指定组匹配的子串的第一个字符在原目标字符串中的位置。
(光看方法的解释是不是很不好理解?不要急,待会结合例子就比较容易明白了)
一个Matcher实例是被用来对目标字符串进行基于既有模式(也就是一个给定的Pattern所编译的正则表达式)进行匹配查找的,所有往Matcher的输入都是通过CharSequence接口提供的,这样做的目的在于可以支持对从多元化的数据源所提供的数据进行匹配工作。
我们分别来看看各方法的使用:
★matches()/lookingAt ()/find():
一个Matcher对象是由一个Pattern对象调用其matcher()方法而生成的,一旦该Matcher对象生成,它就可以进行三种不同的匹配查找操作:
matches()方法尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值。
lookingAt ()方法将检测目标字符串是否以匹配的子串起始。
find()方法尝试在目标字符串里查找下一个匹配子串。
以上三个方法都将返回一个布尔值来表明成功与否。
★replaceAll ()/appendReplacement()/appendTail():
Matcher类同时提供了四个将匹配子串替换成指定字符串的方法:
replaceAll()
replaceFirst()
appendReplacement()
appendTail()
replaceAll()与replaceFirst()的用法都比较简单,请看上面方法的解释。我们主要重点了解一下appendReplacement()和appendTail()方法。
appendReplacement(StringBuffer sb, String replacement) 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里,而appendTail(StringBuffer sb) 方法则将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
例如,有字符串fatcatfatcatfat,假设既有正则表达式模式为"cat",第一次匹配后调用appendReplacement(sb,"dog"),那么这时StringBuffer sb的内容为fatdog,也就是fatcat中的cat被替换为dog并且与匹配子串前的内容加到sb里,而第二次匹配后调用appendReplacement(sb,"dog"),那么sb的内容就变为fatdogfatdog,如果最后再调用一次appendTail(sb),那么sb最终的内容将是fatdogfatdogfat。
还是有点模糊?那么我们来看个简单的程序:
//该例将把句子里的"Kelvin"改为"Kevin"
import java.util.regex.*;
public class MatcherTest{
public static void main(String[] args)
throws Exception {
//生成Pattern对象并且编译一个简单的正则表达式"Kelvin"
Pattern p = Pattern.compile("Kevin");
//用Pattern类的matcher()方法生成一个Matcher对象
Matcher m = p.matcher("Kelvin Li and Kelvin Chan are both working in Kelvin Chen's KelvinSoftShop company");
StringBuffer sb = new StringBuffer();
int i=0;
//使用find()方法查找第一个匹配的对象
boolean result = m.find();
//使用循环将句子里所有的kelvin找出并替换再将内容加到sb里
while(result) {
i++;
m.appendReplacement(sb, "Kevin");
System.out.println("第"+i+"次匹配后sb的内容是:"+sb);
//继续查找下一个匹配对象
result = m.find();
}
//最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里;
m.appendTail(sb);
System.out.println("调用m.appendTail(sb)后sb的最终内容是:"+ sb.toString());
}
}
最终输出结果为:
第1次匹配后sb的内容是:Kevin
第2次匹配后sb的内容是:Kevin Li and Kevin
第3次匹配后sb的内容是:Kevin Li and Kevin Chan are both working in Kevin
第4次匹配后sb的内容是:Kevin Li and Kevin Chan are both working in Kevin Chen's Kevin
调用m.appendTail(sb)后sb的最终内容是:Kevin Li and Kevin Chan are both working in Kevin Chen's KevinSoftShop company.
看了上面这个例程是否对appendReplacement(),appendTail()两个方法的使用更清楚呢,如果还是不太肯定最好自己动手写几行代码测试一下。
★group()/group(int group)/groupCount():
该系列方法与我们在上篇介绍的Jakarta-ORO中的MatchResult .group()方法类似(有关Jakarta-ORO请参考上篇的内容),都是要返回与组匹配的子串内容,下面代码将很好解释其用法:
import java.util.regex.*;
public class GroupTest{
public static void main(String[] args)
throws Exception {
Pattern p = Pattern.compile("(ca)(t)");
Matcher m = p.matcher("one cat,two cats in the yard");
StringBuffer sb = new StringBuffer();
boolean result = m.find();
System.out.println("该次查找获得匹配组的数量为:"+m.groupCount());
for(int i=1;i<=m
}
}
输出为:
该次查找获得匹配组的数量为:2
第1组的子串内容为:ca
第2组的子串内容为:t
Matcher对象的其他方法因比较好理解且由于篇幅有限,请读者自己编程验证。
4.一个检验Email地址的小程序:
最后我们来看一个检验Email地址的例程,该程序是用来检验一个输入的EMAIL地址里所包含的字符是否合法,虽然这不是一个完整的EMAIL地址检验程序,它不能检验所有可能出现的情况,但在必要时您可以在其基础上增加所需功能。


代码如下:

import java.util.regex.*;
public class Email {
public static void main(String[] args) throws Exception {
String input = args[0];
//检测输入的EMAIL地址是否以 非法符号"."或"@"作为起始字符
Pattern p = Pattern.compile("^.|^@");
Matcher m = p.matcher(input);
if (m
//检测是否以"www."为起始
p = Pattern.compile("^www.");
m = p.matcher(input);
if (m
//检测是否包含非法字符
p = Pattern.compile("[^A-Za-z0-9.@_-~#]+");
m = p.matcher(input);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
boolean deletedIllegalChars = false;
while(result) {
//如果找到了非法字符那么就设下标记
deletedIllegalChars = true;
//如果里面包含非法字符如冒号双引号等,那么就把他们消去,加到SB里面
m.appendReplacement(sb, "");
result = m.find();
}
m.appendTail(sb);
input = sb.toString();
if (deletedIllegalChars) {
System.out.println("输入的EMAIL地址里包含有冒号、逗号等非法字符,请修改");
System.out.println("您现在的输入为: "+args[0]);
System.out.println("修改后合法的地址应类似: "+input);
}
}
}

例如,我们在命令行输入:java Email www.kevin@163.net
那么输出结果将会是:EMAIL地址不能以'www.'起始
如果输入的EMAIL为@kevin@163.net
则输出为:EMAIL地址不能以'.'或'@'作为起始字符
当输入为:cgjmail#$%@163.net
那么输出就是:
输入的EMAIL地址里包含有冒号、逗号等非法字符,请修改
您现在的输入为: cgjmail#$%@163.net
修改后合法的地址应类似: cgjmail@163.net
5.总结:
本文介绍了jdk1.4.0-beta3里正则表达式库--java.util.regex中的类以及其方法,如果结合与上一篇中所介绍的Jakarta-ORO API作比较,读者会更容易掌握该API的使用,当然该库的性能将在未来的日子里不断扩展,希望获得最新信息的读者最好到及时到SUN的网站去了解。
6.结束语:
本来计划再多写一篇介绍一下需付费的正则表达式库中较具代表性的作品,但觉得既然有了免费且优秀的正则表达式库可以使用,何必还要去找需付费的呢,相信很多读者也是这么想的:,所以有兴趣了解更多其他的第三方正则表达式库的朋友可以自己到网上查找或者到我在参考资料里提供的网址去看看。
参考资料
java.util.regex的帮助文档
Dana Nourie 和Mike McCloskey所写的Regular Expressions and the Java™ Programming Language
需要更多的第三方正则表达式资源以及基于它们所开发的应用程序请看http://www.meurrens.org/ip-Links/java/regex/index.html

(0)

相关推荐

  • Java环境变量的设置方法(图文教程)

    安装JDK 向导进行相关参数设置.如图: 正在安装程序的相关功能,如图: 选择安装的路径,可以自定义,也可以默认路径.如图: 成功安装之后,进行测试是否真的成功安装,点击[开始]----[运行]----输入 CMD,在命令提示符里面输入"Java -version"并按回车键,出现下图,即为安装成功.如图: 下面开始配置环境变量,右击[我的电脑]---[属性]-----[高级]---[环境变量],如图: 选择[新建系统变量]--弹出"新建系统变量"对话框,在&quo

  • JAVA8 十大新特性详解

    "Java is still not dead-and people are starting to figure that out." 本教程将用带注释的简单代码来描述新特性,你将看不到大片吓人的文字. 一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下: 复制代码 代码如下: interface Formula {    double calculate(int a); default do

  • java list用法示例详解

    |--List:元素是有序的(怎么存的就怎么取出来,顺序不会乱),元素可以重复(角标1上有个3,角标2上也可以有个3)因为该集合体系有索引,  |-- ArrayList:底层的数据结构使用的是数组结构(数组长度是可变的百分之五十延长)(特点是查询很快,但增删较慢)线程不同步  |-- LinkedList:底层的数据结构是链表结构(特点是查询较慢,增删较快)  |-- Vector:底层是数组数据结构 线程同步(数组长度是可变的百分之百延长)(无论查询还是增删都很慢,被ArrayList替代了

  • JavaWeb实现文件上传下载功能实例解析

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件.这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,stru

  • Java Benchmark 基准测试的实例详解

    Java Benchmark 基准测试的实例详解 import java.util.Arrays; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Measurement; import org.openjdk

  • java中File类的使用方法

    构造函数 复制代码 代码如下: public class FileDemo {     public static void main(String[] args){         //构造函数File(String pathname)         File f1 =new File("c:\\abc\\1.txt");         //File(String parent,String child)         File f2 =new File("c:\\a

  • Java正则表达式Pattern和Matcher原理详解

    这篇文章主要介绍了Java正则表达式Pattern和Matcher原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 基本使用 Scanner中的使用正则表达式 //Scanner 支持的分组 Scanner cin=new Scanner("red a bbc").useDelimiter("\\s*a\\s*"); System.out.println(cin.next()); System.out.pri

  • JAVA正则表达式 Pattern和Matcher

    1.简介: java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包. 它包括两个类:Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表现模式. Matcher 一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查. 首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字

  • java正则表达式之Pattern与Matcher类详解

    Pattern.split方法详解 /** * 测试Pattern.split方法 */ @Test public void testPatternSplit() { String str = "{0x40, 0x11, 0x00, 0x00}"; // 分割符为:逗号, {,}, 空白符 String regex = "[,\\{\\}\\s]"; Pattern pattern = Pattern.compile(regex); /* * 1. split 方法

  • 常用java正则表达式的工具类

    本文实例为大家分享了java正则表达式工具类的具体代码,供大家参考,具体内容如下 import com.google.common.base.Strings; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 常用的正则表达式 * Created by tookbra on 2016/4/7. */ public class RegexUtils { /** * 判断是否是正确的IP地址 * * @para

  • Java正则表达式学习之分组与替换

    正则表达式的子表达式(分组)不是很好懂,但却是很强大的文本处理工具. 1 正则表达式热身 匹配电话号码 // 电话号码匹配 // 手机号段只有 13xxx 15xxx 18xxxx 17xxx System.out.println("18304072984".matches("1[3578]\\d{9}")); // true // 座机号:010-65784236,0316-3312617,022-12465647,03123312336 String regex

  • Java正则表达式之Pattern类实例详解

    目录 前言 Pattern 概述 Pattern 匹配模式(Pattern flags) 代码示例 多行模式:Pattern.MULTILINE 示例 忽略大小写:Pattern.CASE_INSENSITIVE 示例 启用注释:Pattern.COMMENTS 示例 启用 dotall 模式:Pattern.DOTALL 示例 平白字符模式 模式:Pattern.LITERAL 示例 附:贪婪匹配与懒惰匹配 总结 前言 这个系列的文章我们使用以下的顺序进行讲解: Pattern 详解: Mat

  • 详解Java正则表达式中Pattern类和Matcher类

    前言 本文将介绍Java正则表达式中的Pattern类与Matcher类.首先我们要清楚指定为字符串的正则表达式必须首先被编译为pattern类的实例.因此如何更好的了解这两个类,是编程人员必须知道的. 以下我们就分别来看看这两个类: 一.捕获组的概念 捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的.例如,在表达式 ((A)(B(C)))中,存在四个这样的组: 1 ((A)(B(C))) 2 (A) 3 (B(C)) 4 (C) 组零始终代表整个表达式. 以 (?) 开头的组是纯的

  • Java正则相关的Pattern和Matcher类及遇到的坑

    此篇文章是记录我在学习Java正则表达式时候学到的和遇到的坑. 先来说说 Matcher 里面的三个方法(取的结果以group()方法为例子) matches():整个匹配,只有整个字符序列完全匹配成功,才返回True,否则返回False.但如果前部分匹配成功,将移动下次匹配的位置.举个例子如果字符串为"a123",正则表达式为"\w\d\d\d",则matches()方法才返回true,换言之,就是要匹配的字符串需要跟正则表达式一一对应,字母对应字母,数字对应数字

  • Java Pattern和Matcher字符匹配方式

    目录 Pattern类定义 因此,典型的调用顺序是: Pattern类方法详解 Pattern类使用示例: Matcher类定义 Matcher类方法详解 1.Matcher类提供了三个匹配操作方法 2.返回匹配器的显示状态 3.int start(),int end(),int group()均有一个重载方法 4.Matcher类同时提供了四个将匹配子串替换成指定字符串的方法: 5.其他一些方法: 应用实例 Pattern类定义 public final class Pattern exten

  • Java Pattern与Matcher字符串匹配案例详解

    Pattern类定义          public final class Pattern extends Object implementsSerializable正则表达式的编译表示形式.用于编译正则表达式后创建一个匹配模式.         指定为字符串的正则表达式必须首先被编译为此类的实例.然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配.执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式.         因此,典型的

随机推荐