javareplaceall捕获组_java正则表达式获取⼤括号之间的内容先说下组的概念:
捕获组
捕获组是把多个字符当⼀个单独单元进⾏处理的⽅法,它通过对括号内的字符分组来创建。
例如,正则表达式 (dog) 创建了单⼀分组,组⾥包含"d","o",和"g"。
捕获组是通过从左⾄右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
((A)(B(C)))
(A)
(B(C))
(C)
可以通过调⽤ matcher 对象的 groupCount ⽅法来查看表达式有多少个分组。groupCount ⽅法返回⼀个 int 值,表⽰matcher对象当前有多个捕获组。
还有⼀个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。
Java正则表达式匹配模式[贪婪型、勉强型、占有型],默认情况是贪婪模式匹配
贪婪模式表达式:
表达式
含义
X?
X,⼀次或⼀次也没有
X*
X,零次或多次
X+
X,⼀次或多次
X{n}
X,恰好 n 次
X{n,}
X,⾄少 n 次
X{n,m}
X,⾄少 n 次,但是不超过 m 次
⾮贪婪模式表达式:
表达式
含义
X??
X,⼀次或⼀次也没有
X*?
X,零次或多次
X+?
X,⼀次或多次
X{n}?
X,恰好 n 次
X{n,}?
X,⾄少 n 次
X{n,m}?
X,⾄少 n 次,但是不超过 m 次
对于这三种匹配模式也有叫: “最⼤匹配Greedy”“最⼩匹配Reluctant”“完全匹配Possessive”。现在将我对这三种匹配模式的理解写出来,并提供⼀些例⼦供⼤家参考。
1、Greediness(贪婪型): 最⼤匹配
X?、X*、X+、X{n,}都是最⼤匹配。例如你要⽤“<.>”去匹配“a
aava abb”,也许你所期待的结果是想匹配“”,但是实际结果却会匹配到“aava ”。这是为什么呢?下⾯我们跟踪下最⼤匹配的匹配过程。
①“
②“.+”匹配字符串的“
aava ab”,在进⾏最⼤匹配时,它把两个“>”都匹配了,它匹配了所有字符,直到⽂本的最后字符“b”
③这时,发现不能成功匹配“>”,开始按原路回退,⽤“a”与“>”匹配,直到“ab”前⾯的“>”匹配成功。
这就是最⼤匹配,我们匹配的时候应该看最后⾯能匹配到哪。
代码⽰例:
String test = "a
aava abb ";
String reg = "<.>";
System.out.placeAll(reg, "###"));
输出:
a###abb
2、Reluctant(Laziness)(勉强型):最⼩匹配
X?、X*、X+、X{n,}都是最⼤匹配。好,加个?就成了Laziness匹配。例如X??、X*?、X+?、X{n,}?都是最⼩匹配,其实X{n,m}?和X{n }?有些多余。
最⼩匹配意味者,.+? 匹配⼀个字符后,马上试⼀试>的匹配可能,失败了,则.+? 再匹配⼀个字符,再马上试⼀试>的匹配可能。JDK⽂档中Greedy 和 Reluctant,它是以eat⼀⼝来隐喻的,所以翻译成贪吃和(勉强的)厌⾷最贴切了。不过我喜欢最⼤匹配、最⼩匹配的说法。
代码⽰例:
String test = "a
aava abb ";
String reg = "<.>";
System.out.placeAll(reg, "###"));
输出:
a###aava ###abb
和上⾯的不同是匹配了两处。
3、Possessive(占有型):完全匹配
与最⼤匹配不同,还有⼀种匹配形式:X?+、X*+、X++、X{n,}+等,成为完全匹配。它和最⼤匹配⼀样,⼀直匹配所有的字符,直到⽂本的最后,但它不由原路返回。也就是说,⼀⼝匹配,搞不定就算了,到也⼲脆,偶喜欢。
代码⽰例:
String test = "a
aava abb ";
String test2 = "
";
String reg = "<.>";
String reg2 = "
";
System.out.placeAll(reg, "###"));
System.out.placeAll(reg2, "###"));
输出:
a
aava abb
###
可见。完全匹配是最严格的,必须整个字符串匹配才⾏。
实例: 获取下⾯字符串中的⼤括号中的内容:
{one}{two}{three}
可以这样:
String s = "{one}{two}{three}";
//因为默认为贪婪模式,所以如果没有使⽤显⽰()组中的元素不能为⼤括号([^}]*),⽽是使⽤(.*),
//那么会匹配的字符串为:one}{two}{three
Pattern p = Patternpile("\\{([^}]*)\\}");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.up(1));//第⼀次匹配成功是one,第⼆次匹配成功是two,第三次匹配为three
}
输出
one
two
three
如果想要三个⼤括号中的 内容⼀起输出,可以这样:
String s = "{one}{two}{three}";
Pattern p = Patternpile("\\{([^}]*)\\}\\{([^}]*)\\}\\{([^}]*)\\}");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.up(1) + ", " + m.group(2) + ", " + m.group(3));//获取该次匹配中组(),正则表达式中只有⼀个(),即只分了⼀个组
}replaceall()
输出
one, two, three
关于组的实例:
import Matcher;
import Pattern;
public class RegexMatches
{
public static void main( String args[] ){
// 按指定模式在字符串查
String line = "This order was placed for QT3000! OK?";
String pattern = "(\\D*)(\\d+)(.*)";
// 创建 Pattern 对象
Pattern r = Patternpile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find( )) {
//每次匹配成功之后,表⽰利⽤pattern 获取到了匹配的字符串,⽽pattern 中有三个⼩括号,即有三个
//组,那么每次匹配成功肯定有group(1),group(2),group(3),group(0)是它总是代表整个表达式
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
System.out.println("Found value: " + m.group(3) );
} else {
System.out.println("NO MATCH");
}
}
}
运⾏结果如下:
Found value: This order was placed for QT3000! OK? Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论