您的位置:首页 > 编程语言 > Java开发

Java正则表达式详解

2017-07-06 00:00 211 查看
在本章之前,建议先查看上章:Java正则表达式--30分钟入门教程和查看C#的正则表达式30分钟入门教程

本章主要对Pattern、Matcher 、PatternSyntaxException、MatchResult类中方法进行测试,以及介绍\num、\n、\nm、\nml、\nml的含义及实际使用,本章中的环境为JDK1.8。

一、Pattern类中的方法如下:



1.静态方法有4个:

public static Pattern compile(String regex)

返回Pattern对象,注意和compile(String regex, int flags)方法无交集。

public static Pattern compile(String regex, int flags)

返回Pattern对象,flags参数为



public static boolean matches(String regex, CharSequence input)

检查input字符队列是否满足regex表达式,测试代码如下:

@Test
public void test(){
String regex = "[0-9].*125";
String str1 = "5sdfsd125";
String str2 = "dsfs5sdfsdfsd125sd";
boolean matches = Pattern.matches(regex, str1);
boolean matches2 = Pattern.matches(regex, str2);
System.out.println(matches+"---"+matches2);
}
结果:true---false
public static String quote(String s)

借鉴链接http://blog.csdn.net/yin380697242/article/details/52050023

调用改方法产生的字符串只匹配和它完全相同的内容,

深入源码:

public static String quote(String s) {
int slashEIndex = s.indexOf("\\E");
if (slashEIndex == -1)
return "\\Q" + s + "\\E";
StringBuilder sb = new StringBuilder(s.length() * 2);
sb.append("\\Q");
slashEIndex = 0;
int current = 0;
while ((slashEIndex = s.indexOf("\\E", current)) != -1) {
sb.append(s.substring(current, slashEIndex));
current = slashEIndex + 2;
sb.append("\\E\\\\E\\Q");
}
sb.append(s.substring(current, s.length()));
sb.append("\\E");
return sb.toString();
}
可以看到,假如不包含“\\E”,则返回的字符串加"\\Q"和 "\\E",假如包含“\\E”,则加"\\Q"和 "\\E"外,把每个“\\E”替换成"\\E\\\\E\\Q"。你只需要记得调用改方法产生的字符串只匹配和它完全相同的内容即可。

2.非静态方法有8个

public String pattern()和public String toString()

@Test
public void test(){
&nb
7fe0
sp; String regex = "\\d.*125";
Pattern compile = Pattern.compile(regex);
System.out.println(compile.pattern());
}
结果:\d.*125
public int flags()这两个方法完全相同,返回此模式的匹配标志

返回flags的输入模式值,不输入为0

public Matcher matcher(CharSequence input) :注意:只有此方法生成匹配器。

创建匹配给定输入与此模式的匹配器。

public String[] split(CharSequence input)

对输入字符队列按照某规则进行拆分,默认忽略数组末尾空串,相当于下面的limit参数为0

public String[] split(CharSequence input, int limit):该方法在一定程度上相当于String的split()方法。

注意:拆分时将删除和拆分规则相同的内容

limit 参数控制模式应用的次数,因此影响所得数组的长度。如果该限制 n 大于 0,则模式将被最多应用 n - 1 次,数组的长度将不会大于 n,而且数组的最后一项将包含所有超出最后匹配的定界符的输入。如果 n 为非正,那么模式将被应用尽可能多的次数,而且数组可以是任何长度。如果 n 为 0,那么模式将被应用尽可能多的次数,数组可以是任何长度,并且结尾空字符串将被丢弃。

public Predicate<String> asPredicate()

public Predicate<String> asPredicate() {
return s -> matcher(s).find();
}
源码如上,返回类型为Predicate,String是Predicate的方法参数类型,其实jdk1.8新增的重要函数式接口,return的是一个Predicate接口的Lambda表达式形式的匿名实现类,该方法可在调用Predicate的test()方法时,可看做boolean matches(String regex, CharSequence input)方法。

public Stream<String> splitAsStream(final CharSequence input)

可对比split(CharSequence input),只是返回的是Stream对象,关于Stream可以自行学习,它是jdk1.8新增的重要特性,专为集合和数组服务。

二、Matcher类中的方法如下



1.静态方法有1个:

public static String quoteReplacement(String s)

返回指定
String
的字面值替换
String
。类似于Pattern的quote()方法,不同的是quoteReplacement讲s中的“\\”和“$”前面加“\\”返回,看源码

public static String quoteReplacement(String s) {
if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1))
return s;
StringBuilder sb = new StringBuilder();
for (int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if (c == '\\' || c == '$') {
sb.append('\\');
}
sb.append(c);
}
return sb.toString();
}
2.非静态方法有33个

2.1public Pattern pattern()

返回该生成该匹配器的pattern,代表着之前的正则可以重复使用

2.2public Matcher usePattern(Pattern newPattern)

更改此 Matcher 用于查找匹配项的 Pattern。此方法可导致匹配器丢失有关最后发生匹配的组的信息。维持了输入中匹配器的位置并且不影响其最后添加的位置

2.3public int start()

返回以前匹配的初始索引。注意:执行此方法前需要匹配过,否则报IllegalStateException,每匹配一次,值会更新

2.4public boolean matches()

完全匹配才是true,相当于Pattern的matches方法

2.5public boolean find()

对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true

Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.lookingAt();//返回true,因为\d+匹配到了前面的22
Matcher m2=p.matcher("aa2223");
m2.lookingAt();//返回false,因为\d+不能匹配前面的aa
借鉴链接:http://blog.csdn.net/cclovett/article/details/12448843/
方法扫描输入序列以查找与该模式匹配的下一个子序列,注意:该方法每次执行只要返回false,则first属性值置-1.

2.6 public int start(String name)

在此说明一下正则中的组名称,该方法是在jdk1.8中才支持的,借鉴链接:

https://www.crifan.com/java_util_regex_named_group/,组的命名和使用如下:

(?<groupName>X) 定义一个名为groupName的组

\\k<groupName> 用于向后引用(back reference)名为groupName的组

${groupName} 用于,在替换函数中,后向引用名为groupName的组

group(groupName) 用于获得对应的带捕获的名为groupName的组的值

2.7 public Matcher reset()

重置匹配器,返回新创建时的状态

2.8 public boolean find(int start)

重设Matcher对象,并且尝试在目标字符串里从指定的位置开始查找下一个匹配的子串,其会前调用reset()方法

2.9 public StringBuffer appendTail(StringBuffer sb)

将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里

2.10 public String replaceFirst(String replacement)

将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串

2.11 public String replaceAll(String replacement)

将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串

注意:执行完replaceFirst、replaceAll方法后对Matter对象的影响

2.12 public Matcher appendReplacement(StringBuffer sb, String replacement)

@Test
public void test(){
String regex = "\\d.*?125";
String str2 = "65465125";
String str = "sdsf56545125sdsf56545125sdsf56545125sdsf56545125";
Pattern compile = Pattern.compile(regex);
// System.err.println(compile.matches(regex, str));
Matcher matcher = compile.matcher(str);
boolean find = matcher.find();
int end = matcher.end();
System.err.println(end);
boolean find2 = matcher.find();
end = matcher.end();
boolean find3 = matcher.find();
end = matcher.end();
System.err.println(end);
System.err.println(find2);
StringBuffer sb = new StringBuffer();
matcher.appendReplacement(sb, "替换后的");
// System.err.println("----------"+find);
// int start = matcher.start();
System.out.println(sb.toString());
}
结果:
12
36
true
sdsf56545125sdsf56545125sdsf替换后的
很明显,appendReplacement(StringBuffer sb, String replacement) 为将本次匹配开始位置之前的字符和本次替换的字符串放入到了传入StringBuffer对象中。

2.13 public int start(int group)

获取group组的上一次匹配下标,组在正则中定义,每匹配一次值会变动,若没有对应的组,将抛出IndexOutOfBoundsException异常

2.14 public int end()

和start()方法一样,区别是上次匹配的最后位置下标。

2.15 public int end(int group)

和start(group)方法一样,区别是上次匹配的第group组的最后位置下标

2.16 public int end(String name)

和start(name)方法一样,区别是上次匹配的name组的最后位置下标

2.17 public int groupCount()

返回该正则表达式的组数量

2.18 public String group()

返回上次匹配的组0及上次匹配的内容

2.19 public String group(int group)

返回上次匹配的第group组的内容

2.20 public String group(String name)

返回上次匹配的name组的内容

2.21 public Matcher reset(CharSequence input)

重设该Matcher对象并且指定一个新的目标字符串

2.22 public MatchResult toMatchResult()

将上次的匹配结果转化为MatchResult对象,其实Matcher对象实现了MatchResult接口,多态时可能有用吧,具体方法将在MatchResult中简单介绍。

2.23 public boolean lookingAt()

检查是否以符合正则要求的字符队列开头,注意:假如返回为true,调用改方法后,相当于第一此调用find()方法

2.24 public Matcher region(int start, int end)

设置上次可以匹配的范围

2.25 public int regionStart()

当前开始匹配的位置

2.26 public int regionEnd()

当前结束匹配的位置

2.27 public String toString()

public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("java.util.regex.Matcher");
sb.append("[pattern=" + pattern());
sb.append(" region=");
sb.append(regionStart() + "," + regionEnd());
sb.append(" lastmatch=");
if ((first >= 0) && (group() != null)) {
sb.append(group());
}
sb.append("]");
return sb.toString();
}
没什么说的,就是按照一定格式打印最后一次匹配的内容

2.28 还有6个,实验发现不起作用,下次再介绍

三、MatchResult类中方法如下:



其是一个接口,存储某次检索匹配到的内容,Matcher实现了该接口。其方法在Matcher都介绍过了,在此就不重复介绍了。

四、PatternSyntaxException

抛出未经检查的异常,以指示正则表达式模式中的语法错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java正则表达式