📄 java中正则表达式的应用-java面向对象 - it电子教育门户 高端java培训.htm
字号:
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。)}<BR>之前,我们已经了解Util.substitute()方法与Substiution接口,以及Substiution的两个实现类StringSubstitution和Perl5Substitution,我们就来看看怎么用Util.substitute()方法配合Perl5Substitution来完成我们上面提出的替换要求,确定正则表达式:<BR>我们要先找到其中的整个例句部分,也就是由大括号包起来的字串,并且把两个例句分别分组,所以正则表达式为:"\{(\([^)]+\))(\([^)]+\))\}",如果用替换变量来代替分组,那么上面的表达式可以看为"\{$1$2\}",这样就可以更容易看出替换变量与分组间的关系。<BR>根据上面的正则表达式Perl5Substitution类可以这样构造:<BR>Perl5Substitution("{$1(
Kevin has seen《LEON》seveal times,because it is a good film./
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。)}")<BR>再根据这个Perl5Substitution对象来使用Util.substitute()方法便可以完成替换了,实现的代码片段如下:<BR>try{<BR>
String content="['kevin] [名词](人名凯文){(Kevin loves
comic./凯文爱漫画/名词: 凯文)(Kevin lives in ZhuHai now./凯文现住在珠海/名词:
凯文)}";<BR> String
ps1="\\{(\\([^)]+\\))(\\([^)]+\\))\\}";<BR> String
sentence;<BR> String pure;<BR>
PatternCompiler orocom=new Perl5Compiler();<BR>
Pattern pattern1=orocom.compile(ps1);<BR>
PatternMatcher matcher=new
Perl5Matcher();<BR> String
result=Util.substitute(matcher,<BR>
pattern1,new
Perl5Substitution(<BR>
"{$1( Kevin has seen《LEON》seveal times,because it is a good
film./
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。)}",1),<BR>
content,Util.SUBSTITUTE_ALL);<BR>
System.out.println(result);<BR> }<BR>
catch(Exception e)
{<BR>
System.out.println(e);<BR>
}<BR> <BR> </P>
<P><BR>输出结果是正确的,为:<BR>['kevin] [名词](人名凯文){(Kevin loves
comic./凯文爱漫画/名词: 凯文)( Kevin has seen《LEON》seveal times,because
it is a good film./
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。)}<BR>至于有关使用numInterpolations参数的构造器用法,读者只要根据上面的介绍自己动手试一下就会清楚了,在此就不再例述。<BR>总结:<BR>本文首先介绍了Jakarta-ORO正则表达式库的对象与方法,并且接着举例让读者对实际应用有进一步的了解,虽然例子都比较简单,但希望读者们在看了该文后对Jakarta-ORO正则表达式库有一定的认知,在实际工作中有所帮助与启发。<BR>其实在Jakarta
org里除了Jakarta-ORO外还有一个百分百的纯JAVA正则表达式库,就是由Jonathan
Locke赠与Jakarta
ORG的Regexp,在该包里面包含了完整的文档以及一个用于调试的Applet例子,对其有兴趣的读者可以到此下载。<BR>参考资料:<BR>本文的主要参考文章,该文在介绍Jakarta-ORO的同时也为读者详尽解析了正则表达式的基本语法。
<BR>一个基于PERL的正则表达式详尽教程(虽然该教程是基于PERL的,但是你并不需要有PERL的经验,虽然那会有所帮助),以及一个不错的正则表达式简例教程。
<BR>最不可缺少的当然是Jakarta-ORO的帮助文档http://jakarta.apache.org/oro/api/
</P>
<P><BR>1.简介:<BR>java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。<BR>它包括两个类:Pattern和Matcher<BR>Pattern
一个Pattern是一个正则表达式经编译后的表现模式。 <BR>Matcher
一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。 </P>
<P><BR>首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。<BR>以下我们就分别来看看这两个类:<BR>2.Pattern类:<BR>Pattern的方法如下:<BR>static
Pattern compile(String regex)<BR>将给定的正则表达式编译并赋予给Pattern类
<BR>static Pattern compile(String regex, int
flags)<BR>同上,但增加flag参数的指定,可选的flag参数包括:CASE
INSENSITIVE,MULTILINE,DOTALL,UNICODE CASE, CANON EQ <BR>int
flags()<BR>返回当前Pattern的匹配flag参数. <BR>Matcher
matcher(CharSequence input)<BR>生成一个给定命名的Matcher对象 <BR>static
boolean matches(String regex, CharSequence
input)<BR>编译给定的正则表达式并且对输入的字串以该正则表达式为模开展匹配,该方法适合于该正则表达式只会使用一次的情况,也就是只进行一次匹配工作,因为这种情况下并不需要生成一个Matcher实例。
<BR>String pattern()<BR>返回该Patter对象所编译的正则表达式。 <BR>String[]
split(CharSequence input)<BR>将目标字符串按照Pattern里所包含的正则表达式为模进行分割。
<BR>String[] split(CharSequence input, int
limit)<BR>作用同上,增加参数limit目的在于要指定分割的段数,如将limi设为2,那么目标字符串将根据正则表达式分为割为两段。
</P>
<P>一个正则表达式,也就是一串有特定意义的字符,必须首先要编译成为一个Pattern类的实例,这个Pattern对象将会使用
matcher()方法来生成一个Matcher实例,接着便可以使用该
Matcher实例以编译的正则表达式为基础对目标字符串进行匹配工作,多个Matcher是可以共用一个Pattern对象的。<BR>现在我们先来看一个简单的例子,再通过分析它来了解怎样生成一个Pattern对象并且编译一个正则表达式,最后根据这个正则表达式将目标字符串进行分割:<BR>import
java.util.regex.*;<BR>public class
Replacement{<BR> public static
void main(String[] args) throws Exception
{<BR> //
生成一个Pattern,同时编译一个正则表达式<BR>
Pattern p =
Pattern.compile("[/]+");<BR>
//用Pattern的split()方法把字符串按"/"分割<BR>
String[] result = p.split(<BR>"Kevin has seen《LEON》seveal
times,because it is a good film."<BR>+"/
凯文已经看过《这个杀手不太冷》几次了,因为它是一部"<BR>+"好电影。/名词:凯文。");<BR>
for (int i=0; i<result.length;
i++)<BR>
System.out.println(result[i]);<BR>
}<BR>}<BR> <BR> </P>
<P><BR>输出结果为:<BR>Kevin has seen《LEON》seveal times,because it
is a good film.<BR>凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。<BR>名词:凯文。</P>
<P>很明显,该程序将字符串按"/"进行了分段,我们以下再使用 split(CharSequence input, int
limit)方法来指定分段的段数,程序改动为:<BR>tring[] result = p.split("Kevin has
seen《LEON》seveal times,because it is a good film./
凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。",2);<BR>这里面的参数"2"表明将目标语句分为两段。<BR>输出结果则为:<BR>Kevin
has seen《LEON》seveal times,because it is a good
film.<BR>凯文已经看过《这个杀手不太冷》几次了,因为它是一部好电影。/名词:凯文。</P>
<P>由上面的例子,我们可以比较出java.util.regex包在构造Pattern对象以及编译指定的正则表达式的实现手法与我们在上一篇中所介绍的Jakarta-ORO
包在完成同样工作时的差别,Jakarta-ORO
包要先构造一个PatternCompiler类对象接着生成一个Pattern对象,再将正则表达式用该PatternCompiler类的compile()方法来将所需的正则表达式编译赋予Pattern类:<BR>PatternCompiler
orocom=new Perl5Compiler();<BR>Pattern
pattern=orocom.compile("REGULAR
EXPRESSIONS");<BR>PatternMatcher matcher=new
Perl5Matcher();<BR>但是在java.util.regex包里,我们仅需生成一个Pattern类,直接使用它的compile()方法就可以达到同样的效果:<BR>Pattern
p =
Pattern.compile("[/]+");<BR>因此似乎java.util.regex的构造法比Jakarta-ORO更为简洁并容易理解。<BR>3.Matcher类:<BR>Matcher方法如下:<BR>Matcher
appendReplacement(StringBuffer sb, String
replacement)<BR>将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里。
<BR>StringBuffer appendTail(StringBuffer
sb)<BR>将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。 <BR>int
end()<BR>返回当前匹配的子串的最后一个字符在原目标字符串中的索引位置 。 <BR>int end(int
group)<BR>返回与匹配模式里指定的组相匹配的子串最后一个字符的位置。 <BR>boolean
find()<BR>尝试在目标字符串里查找下一个匹配子串。 <BR>boolean find(int
start)<BR>重设Matcher对象,并且尝试在目标字符串里从指定的位置开始查找下一个匹配的子串。
<BR>String group()<BR>返回当前查找而获得的与组匹配的所有子串内容 <BR>String
group(int group)<BR>返回当前查找而获得的与指定的组匹配的子串内容 <BR>int
groupCount()<BR>返回当前查找所获得的匹配组的数量。 <BR>boolean
lookingAt()<BR>检测目标字符串是否以匹配的子串起始。 <BR>boolean
matches()<BR>尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值。
<BR>Pattern pattern()<BR>返回该Matcher对象的现有匹配模式,也就是对应的Pattern 对象。
<BR>String replaceAll(String
replacement)<BR>将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串。 <BR>String
replaceFirst(String
replacement)<BR>将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串。 <BR>Matcher
reset()<BR>重设该Matcher对象。 <BR>Matcher reset(CharSequence
input)<BR>重设该Matcher对象并且指定一个新的目标字符串。 <BR>int
start()<BR>返回当前查找所获子串的开始字符在原目标字符串中的位置。 <BR>int start(int
group)<BR>返回当前查找所获得的和指定组匹配的子串的第一个字符在原目标字符串中的位置。 </P>
<P>(光看方法的解释是不是很不好理解?不要急,待会结合例子就比较容易明白了)<BR>一个Matcher实例是被用来对目标字符串进行基于既有模式(也就是一个给定的Pattern所编译的正则表达式)进行匹配查找的,所有往Matcher的输入都是通过CharSequence接口提供的,这样做的目的在于可以支持对从多元化的数据源所提供的数据进行匹配工作。<BR>我们分别来看看各方法的使用:<BR>★matches()/lookingAt
()/find():<BR>一个Matcher对象是由一个Pattern对象调用其matcher()方法而生成的,一旦该Matcher对象生成,它就可以进行三种不同的匹配查找操作:<BR>matches()方法尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值。
<BR>lookingAt ()方法将检测目标字符串是否以匹配的子串起始。
<BR>find()方法尝试在目标字符串里查找下一个匹配子串。 </P>
<P>以上三个方法都将返回一个布尔值来表明成功与否。<BR>★replaceAll
()/appendReplacement()/appendTail():<BR>Matcher类同时提供了四个将匹配子串替换成指定字符串的方法:<BR>replaceAll()
<BR>replaceFirst() <BR>appendReplacement() <BR>appendTail()
</P>
<P>replaceAll()与replaceFirst()的用法都比较简单,请看上面方法的解释。我们主要重点了解一下appendReplacement()和appendTail()方法。<BR>appendReplacement(StringBuffer
sb, String replacement)
将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里,而appendTail(StringBuffer
sb)
方法则将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。<BR>例如,有字符串fatcatfatcatfat,假设既有正则表达式模式为"cat",第一次匹配后调用appendReplacement(sb,"dog"),那么这时StringBuffer
sb的内容为fatdog,也就是fatcat中的cat被替换为dog并且与匹配子串前的内容加到sb里,而第二次匹配后调用appendReplacement(sb,"dog"),那么sb的内容就变为fatdogfatdog,如果最后再调用一次appendTail(sb),那么sb最终的内容将是fatdogfatdogfat。<BR>还是有点模糊?那么我们来看个简单的程序:<BR>//该例将把句子里的"Kelvin"改为"Kevin"<BR>import
java.util.regex.*;<BR>public class
MatcherTest{<BR> public static void
main(String[] args)
<BR>
throws Exception
{<BR>
//生成Pattern对象并且编译一个简单的正则表达式"Kelvin"<BR>
Pattern p =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -