转载原文章链接:http://www.jb51.cc/article/p-mumenqay-bqm.html
字符组
- 正则表达式的最基本结构之一。
- 作用:规定某个位置能够出现的字符。
- 形式:以”[…]”给出,在方括号内列出字符。或者简写字符。
- 方括号中的字符为某个位置是否出现的字符,例如[123],如果当前位置出现1或者2或者3的话,它都能匹配,但是只能出现一个数字。
例子:
判断十进制字符。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li1 {
public static void main(String[] args) {
String string="4";
String rex="[0123456789]";
Pattern pattern=Pattern.compile(rex);
Matcher matcher=pattern.matcher(string);
System.out.println("/*********本例子用于判断数字是不是十进制*********/");
if(matcher.matches()){
System.out.println("\t\t是十进制数");
}else{
System.out.println("\t\t不是十进制数");
}
}
}
运行结果:
/*********本例子用于判断数字是不是十进制*********/
是十进制数
连字符
这个是连字符 “-”
但是上面的例子用来表示十进制[0123456789]太过累赘,所以可以使用连字符用来简化,但是连字符只能够简化是相连接,中间没有空缺的。即可以这样表示[0-9]就行了。也可以这样表示[0-789]这样也是可以的,想要表达的意思就是用了连字符只是起到简化的作用。
可以测试下:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li1 {
public static void main(String[] args) {
String string="4";
String rex="[0-9]";
Pattern pattern=Pattern.compile(rex);
Matcher matcher=pattern.matcher(string);
System.out.println("/*********本例子用于判断数字是不是十进制*********/");
if(matcher.matches()){
System.out.println("\t\t是十进制数");
}else{
System.out.println("\t\t不是十进制数");
}
}
}
运行结果:
/*********本例子用于判断数字是不是十进制*********/
是十进制数
注意事项
- 在字符组的内部,只有当连字符出现在两个字符之间时,才能表示字符的范围;如果出现在字符组的开头或者结尾,则只能够表示单个字符’-‘即连字符本身这个字符。
排除型字符组
- 作用:规定某个位置不容许出现的字符。
- 形式:以”[^…]”给出,在方括号内列出不容许出现的字符。
- 排除型字符组仍然必须匹配一个字符。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li2 {
public static void main(String[] args) {
String [] strs={"1","2","a","A","\n","\t","\r"," ","哈"};
String rex="[^123]";
Pattern pattern=Pattern.compile(rex);
for(String str:strs){
Matcher matcher=pattern.matcher(str);
System.out.println("字符串:"+str+"匹配结果"+"["+matcher.matches()+"]");
}
}
}
运行结果:
字符串:[1]匹配结果[false]
字符串:[2]匹配结果[false]
字符串:[a]匹配结果[true]
字符串:[A]匹配结果[true]
字符串:[
]匹配结果[true]
字符串:[ ]匹配结果[true]
字符串:[
]匹配结果[true]
字符串:[ ]匹配结果[true]
字符串:[哈]匹配结果[true]
所以排除型表示的意思就是排除当前的字符,然后满足其他的所有字符。
字符组简记法
- 对于常用的字符组,正则表达式提供了相应的简记法,方便地表示它们。
- \d 相当于 [0-9]
- \D 相当于 [^0-9]
- \w 相当于 [0-9a-zA-Z_]
- \W相当于 [^0-9a-zA-Z_]
- \s 匹配空白字符(回车\r、换行\n、制表、空格)
- \S 匹配非空白字符
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li3 {
public static void main(String[] args) {
String rex1="\\d";
String rex2="\\D";
String rex3="\\w";
String rex4="\\W";
String rex5="\\s";
String rex6="\\S";
String [] string=new String[]{"1","B","b","呵","!","!"};
System.out.println("/*************\\d****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex1);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"["+str+"]"+"匹配["+rex1+"]");
}else{
System.out.println("字符串:"+"["+str+"]"+"不匹配["+rex1+"]");
}
}
System.out.println("/*************\\D****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex2);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"["+str+"]"+"匹配["+rex2+"]");
}else{
System.out.println("字符串:"+"["+str+"]"+"不匹配["+rex2+"]");
}
}
System.out.println("/*************\\w****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex3);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"["+str+"]"+"匹配["+rex3+"]");
}else{
System.out.println("字符串:"+"["+str+"]"+"不匹配["+rex3+"]");
}
}
System.out.println("/*************\\W****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex4);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"["+str+"]"+"匹配["+rex4+"]");
}else{
System.out.println("字符串:"+"["+str+"]"+"不匹配["+rex4+"]");
}
}
System.out.println("/*************\\s****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex5);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"["+str+"]"+"匹配["+rex5+"]");
}else{
System.out.println("字符串:"+"["+str+"]"+"不匹配["+rex5+"]");
}
}
System.out.println("/*************\\S****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex6);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"["+str+"]"+"匹配["+rex6+"]");
}else{
System.out.println("字符串:"+"["+str+"]"+"不匹配["+rex6+"]");
}
}
}
}
运行结果:
/*************\d****************/
字符串:[1]匹配[\d]
字符串:[2]匹配[\d]
字符串:[A]不匹配[\d]
字符串:[B]不匹配[\d]
字符串:[a]不匹配[\d]
字符串:[b]不匹配[\d]
字符串:[
]不匹配[\d]
字符串:[ ]不匹配[\d]
字符串:[
]不匹配[\d]
字符串:[ ]不匹配[\d]
字符串:[呵]不匹配[\d]
字符串:[!]不匹配[\d]
字符串:[!]不匹配[\d]
/*************\D****************/
字符串:[1]不匹配[\D]
字符串:[2]不匹配[\D]
字符串:[A]匹配[\D]
字符串:[B]匹配[\D]
字符串:[a]匹配[\D]
字符串:[b]匹配[\D]
字符串:[
]匹配[\D]
字符串:[ ]匹配[\D]
字符串:[
]匹配[\D]
字符串:[ ]匹配[\D]
字符串:[呵]匹配[\D]
字符串:[!]匹配[\D]
字符串:[!]匹配[\D]
/*************\w****************/
字符串:[1]匹配[\w]
字符串:[2]匹配[\w]
字符串:[A]匹配[\w]
字符串:[B]匹配[\w]
字符串:[a]匹配[\w]
字符串:[b]匹配[\w]
字符串:[
]不匹配[\w]
字符串:[ ]不匹配[\w]
字符串:[
]不匹配[\w]
字符串:[ ]不匹配[\w]
字符串:[呵]不匹配[\w]
字符串:[!]不匹配[\w]
字符串:[!]不匹配[\w]
/*************\W****************/
字符串:[1]不匹配[\W]
字符串:[2]不匹配[\W]
字符串:[A]不匹配[\W]
字符串:[B]不匹配[\W]
字符串:[a]不匹配[\W]
字符串:[b]不匹配[\W]
字符串:[
]匹配[\W]
字符串:[ ]匹配[\W]
字符串:[
]匹配[\W]
字符串:[ ]匹配[\W]
字符串:[呵]匹配[\W]
字符串:[!]匹配[\W]
字符串:[!]匹配[\W]
/*************\s****************/
字符串:[1]不匹配[\s]
字符串:[2]不匹配[\s]
字符串:[A]不匹配[\s]
字符串:[B]不匹配[\s]
字符串:[a]不匹配[\s]
字符串:[b]不匹配[\s]
字符串:[
]匹配[\s]
字符串:[ ]匹配[\s]
字符串:[
]匹配[\s]
字符串:[ ]匹配[\s]
字符串:[呵]不匹配[\s]
字符串:[!]不匹配[\s]
字符串:[!]不匹配[\s]
/*************\S****************/
字符串:[1]匹配[\S]
字符串:[2]匹配[\S]
字符串:[A]匹配[\S]
字符串:[B]匹配[\S]
字符串:[a]匹配[\S]
字符串:[b]匹配[\S]
字符串:[
]不匹配[\S]
字符串:[ ]不匹配[\S]
字符串:[
]不匹配[\S]
字符串:[ ]不匹配[\S]
字符串:[呵]匹配[\S]
字符串:[!]匹配[\S]
字符串:[!]匹配[\S]
特殊的简记法:点号
- 点号 “.”是一个特殊的字符组简记法,它可以匹配几乎所有的字符。
- “\.”匹配点号本身。
- 在字符组内部,[.]也只能够匹配点号本身。
- 注意:点号不能够匹配换行符及回车符但能匹配制表符。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li4 {
public static void main(String[] args) {
String rex1=".";
String rex2="\\.";
String rex3="[.]";
String [] string=new String[]{"1","!",".","。"};
System.out.println("/*************.****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex1);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex1+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex1+"\"");
}
}
System.out.println("/*************\\.****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex2);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex2+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex2+"\"");
}
}
System.out.println("/*************[.]****************/");
for(String str:string){
Pattern pattern=Pattern.compile(rex3);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex3+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex3+"\"");
}
}
}
}
运行结果:
/*************.****************/
字符串:"1"匹配"."
字符串:"2"匹配"."
字符串:"A"匹配"."
字符串:"B"匹配"."
字符串:"a"匹配"."
字符串:"b"匹配"."
字符串:"
"不匹配"."
字符串:" "匹配"."
字符串:"
"不匹配"."
字符串:" "匹配"."
字符串:"呵"匹配"."
字符串:"!"匹配"."
字符串:"!"匹配"."
字符串:"."匹配"."
字符串:"。"匹配"."
/*************\.****************/
字符串:"1"不匹配"\."
字符串:"2"不匹配"\."
字符串:"A"不匹配"\."
字符串:"B"不匹配"\."
字符串:"a"不匹配"\."
字符串:"b"不匹配"\."
字符串:"
"不匹配"\."
字符串:" "不匹配"\."
字符串:"
"不匹配"\."
字符串:" "不匹配"\."
字符串:"呵"不匹配"\."
字符串:"!"不匹配"\."
字符串:"!"不匹配"\."
字符串:"."匹配"\."
字符串:"。"不匹配"\."
/*************[.]****************/
字符串:"1"不匹配"[.]"
字符串:"2"不匹配"[.]"
字符串:"A"不匹配"[.]"
字符串:"B"不匹配"[.]"
字符串:"a"不匹配"[.]"
字符串:"b"不匹配"[.]"
字符串:"
"不匹配"[.]"
字符串:" "不匹配"[.]"
字符串:"
"不匹配"[.]"
字符串:" "不匹配"[.]"
字符串:"呵"不匹配"[.]"
字符串:"!"不匹配"[.]"
字符串:"!"不匹配"[.]"
字符串:"."匹配"[.]"
字符串:"。"不匹配"[.]"
量词
- 作用:限定之前的字符出现的次数
- 形式:
- “*” :之前的字符可以出现0次到无穷多次
- “+” :之前的字符可以出现1次到无穷多次
- “?” :之前的字符至多只能出现1次,即0次或者1次
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li5 {
public static void main(String[] args) {
String rex1="a*";
String rex2="a?";
String rex3="a+";
String [] string=new String[]{"","aa","aaa"};
System.out.println("/--------------a*-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex1);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex1+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex1+"\"");
}
}
System.out.println("/--------------a?-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex2);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex2+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex2+"\"");
}
}
System.out.println("/--------------a+-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex3);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex3+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex3+"\"");
}
}
}
}
运行结果:
/--------------a*-----------------/
字符串:""匹配"a*"
字符串:"a"匹配"a*"
字符串:"aa"匹配"a*"
字符串:"aaa"匹配"a*"
/--------------a?-----------------/
字符串:""匹配"a?"
字符串:"a"匹配"a?"
字符串:"aa"不匹配"a?"
字符串:"aaa"不匹配"a?"
/--------------a+-----------------/
字符串:""不匹配"a+"
字符串:"a"匹配"a+"
字符串:"aa"匹配"a+"
字符串:"aaa"匹配"a+"
区间量词
- 作用:具体规定字符的出现次数
- 形式:
- {min,max}即最小出现min次最多出现max次
- {min,}即最小出现min次最多为无穷次
- {number}即规定必须出现number次
- “*” 相当于 {0,}
- “+” 相当于{1,}
- “?” 相当于 {0,1}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li6 {
public static void main(String[] args) {
String rex1="a{2,4}";
String rex2="a{2,}";
String rex3="a{3}";
String [] string=new String[]{"","aaa","aaaa","aaaaa","aaaaaa"};
System.out.println("/--------------a{2,4}-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex1);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex1+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex1+"\"");
}
}
System.out.println("/--------------a{2,}-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex2);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex2+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex2+"\"");
}
}
System.out.println("/--------------a{3}-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex3);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex3+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex3+"\"");
}
}
}
}
运行结果:
/--------------a{2,4}-----------------/
字符串:""不匹配"a{2,4}"
字符串:"a"不匹配"a{2,4}"
字符串:"aa"匹配"a{2,4}"
字符串:"aaa"匹配"a{2,4}"
字符串:"aaaa"匹配"a{2,4}"
字符串:"aaaaa"不匹配"a{2,4}"
字符串:"aaaaaa"不匹配"a{2,4}"
/--------------a{2,}-----------------/
字符串:""不匹配"a{2,}"
字符串:"a"不匹配"a{2,}"
字符串:"aa"匹配"a{2,}"
字符串:"aaa"匹配"a{2,}"
字符串:"aaaa"匹配"a{2,}"
字符串:"aaaaa"匹配"a{2,}"
字符串:"aaaaaa"匹配"a{2,}"
/--------------a{3}-----------------/
字符串:""不匹配"a{3}"
字符串:"a"不匹配"a{3}"
字符串:"aa"不匹配"a{3}"
字符串:"aaa"匹配"a{3}"
字符串:"aaaa"不匹配"a{3}"
字符串:"aaaaa"不匹配"a{3}"
字符串:"aaaaaa"不匹配"a{3}"
量词的局限,括号的使用
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li7 {
public static void main(String[] args) {
String rex1="ac+";
String rex2="(ac)+";
String rex3="ac*";
String rex4="(ac)*";
String rex5="ac?";
String rex6="(ac)?";
String [] string=new String[]{"","ac","acc","accc","acacac","acac","c"};
System.out.println("/--------------ac+-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex1);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex1+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex1+"\"");
}
}
System.out.println("/--------------(ac)+-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex2);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex2+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex2+"\"");
}
}
System.out.println("/--------------ac*-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex3);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex3+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex3+"\"");
}
}
System.out.println("/--------------(ac)*-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex4);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex4+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex4+"\"");
}
}
System.out.println("/--------------ac?-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex5);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex5+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex5+"\"");
}
}
System.out.println("/--------------(ac)?-----------------/");
for(String str:string){
Pattern pattern=Pattern.compile(rex6);
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex6+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex6+"\"");
}
}
}
}
运行结果:
/--------------ac+-----------------/
字符串:""不匹配"ac+"
字符串:"ac"匹配"ac+"
字符串:"acc"匹配"ac+"
字符串:"accc"匹配"ac+"
字符串:"acacac"不匹配"ac+"
字符串:"acac"不匹配"ac+"
字符串:"a"不匹配"ac+"
字符串:"c"不匹配"ac+"
/--------------(ac)+-----------------/
字符串:""不匹配"(ac)+"
字符串:"ac"匹配"(ac)+"
字符串:"acc"不匹配"(ac)+"
字符串:"accc"不匹配"(ac)+"
字符串:"acacac"匹配"(ac)+"
字符串:"acac"匹配"(ac)+"
字符串:"a"不匹配"(ac)+"
字符串:"c"不匹配"(ac)+"
/--------------ac*-----------------/
字符串:""不匹配"ac*"
字符串:"ac"匹配"ac*"
字符串:"acc"匹配"ac*"
字符串:"accc"匹配"ac*"
字符串:"acacac"不匹配"ac*"
字符串:"acac"不匹配"ac*"
字符串:"a"匹配"ac*"
字符串:"c"不匹配"ac*"
/--------------(ac)*-----------------/
字符串:""匹配"(ac)*"
字符串:"ac"匹配"(ac)*"
字符串:"acc"不匹配"(ac)*"
字符串:"accc"不匹配"(ac)*"
字符串:"acacac"匹配"(ac)*"
字符串:"acac"匹配"(ac)*"
字符串:"a"不匹配"(ac)*"
字符串:"c"不匹配"(ac)*"
/--------------ac?-----------------/
字符串:""不匹配"ac?"
字符串:"ac"匹配"ac?"
字符串:"acc"不匹配"ac?"
字符串:"accc"不匹配"ac?"
字符串:"acacac"不匹配"ac?"
字符串:"acac"不匹配"ac?"
字符串:"a"匹配"ac?"
字符串:"c"不匹配"ac?"
/--------------(ac)?-----------------/
字符串:""匹配"(ac)?"
字符串:"ac"匹配"(ac)?"
字符串:"acc"不匹配"(ac)?"
字符串:"accc"不匹配"(ac)?"
字符串:"acacac"不匹配"(ac)?"
字符串:"acac"不匹配"(ac)?"
字符串:"a"不匹配"(ac)?"
字符串:"c"不匹配"(ac)?"
括号的用途:多选结构
- 字符组只能表示某个位置可能出现的单个字符,而不能表示某个位置可能出现的字符串。
- 作用:表示某个位置可能出现的字符串,或者可能出现的多个字符串。
- 形式:
- “(…|…)”,在竖线两端添加各个字符串
- “(…|…|…|…)”
public class li8 {
public static void main(String[] args) {
String [] string=new String[]{"this","that","thit"};
String rex="th[ia][st]";
Pattern pattern=Pattern.compile(rex);
for(String str:string){
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex+"\"");
}
}
}
}
运行结果:
字符串:"this"匹配"th[ia][st]"
字符串:"that"匹配"th[ia][st]"
字符串:"thit"匹配"th[ia][st]"
而我们不想匹配错误的单词thit怎么办呢??
看例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li8 {
public static void main(String[] args) {
String [] string=new String[]{"this","thit"};
String rex="this|that";//也可以写成th(is|at) 这样把公共提出来后可以提高正则匹配效率。
Pattern pattern=Pattern.compile(rex);
for(String str:string){
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex+"\"");
}
}
}
}
运行结果:
字符串:"this"匹配"this|that"
字符串:"that"匹配"this|that"
字符串:"thit"不匹配"this|that"
括号的用途:捕获分组
- 作用:将括号内的子表达式捕获的字符串存放到匹配的结果中,供匹配完成后访问。
- 形式: 使用普通的括号”(…)”。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li9 {
public static void main(String[] args) {
String email="webmaster@itcast.net";
String rex="(\\w+)@([\\w.]+)";
Pattern pattern=Pattern.compile(rex);
Matcher matcher=pattern.matcher(email);
if(matcher.find()){
System.out.println("email add is:\t"+matcher.group(0));//默认打印的是整个匹配的结果
System.out.println("username is:\t"+matcher.group(1));//打印从左到右第一个括号内的结果
System.out.println("hostname is:\t"+matcher.group(2));//打印从左到右第二个括号内的结果
}
}
}
运行结果:
email add is: webmaster@itcast.net
username is: webmaster
hostname is: itcast.net
需要强调的是:括号的先后顺序按照左括号的出现顺序编号,编号从1开始。编号0为整个正则表达式的匹配结果!!
捕获分组的注意事项
- 只要使用了括号,就存在捕获分组。
- 捕获分组按照开括号出现的从左到右的顺序编号,编号从1开始,遇到括号嵌套的情况也是如此。
- 如果捕获分组之后存在量词,则匹配结果中,捕获分组保存的是子表达式最后一次的匹配字符串。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li10 {
public static void main(String[] args) {
explainGroupNo();
System.out.println("");
explainGroupQuantifier();
}
public static void explainGroupNo() {
String email = "webmaster@itcast.net";
String regex = "((\\w+)@([\\w.]+))";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(email);
if (m.find()) {
System.out.println("match result:\t" + m.group(0));
System.out.println("group No.1 is:\t" + m.group(1));
System.out.println("group No.2 is:\t" + m.group(2));
System.out.println("group No.3 is:\t" + m.group(3));
}
}
public static void explainGroupQuantifier() {
String email = "webmaster@itcast.net";
String regex = "(\\w)+@([\\w.])+";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(email);
if (m.find()) {
System.out.println("match result:\t" + m.group(0));
System.out.println("group No.1 is:\t" + m.group(1));
System.out.println("group No.2 is:\t" + m.group(2));
}
}
}
运行结果:
match result: webmaster@itcast.net
group No.1 is: webmaster@itcast.net
group No.2 is: webmaster
group No.3 is: itcast.net
match result: webmaster@itcast.net
group No.1 is: r
group No.2 is: t
不捕获文本的括号
- 如果正则表达式很复杂,或者需要处理的文本很长,捕获分组会降低效率。
- 作用:仅仅用来对表达式分组,而不把分组捕获的文本存入结果。
- 形式:”(?:…)”。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li11 {
public static void main(String[] args) {
String email = "webmaster@itcast.net";
String rex="(?:webmaster|admin)@([\\w.]+)";
Pattern pattern=Pattern.compile(rex);
Matcher matcher=pattern.matcher(email);
if(matcher.find()){
System.out.println("match result:\t"+matcher.group(0));
System.out.println("group No.1 is:\t" + matcher.group(1));
//System.out.println(matcher.group(2));
}
}
}
运行结果:
match result: webmaster@itcast.net
group No.1 is: itcast.net
因为只要出现了括号就会存在捕获分组,并且会保存捕获结果,但是使用(?:…)就不会保存捕获结果了。所以当要输出编号为1的时候就输出了第二个括号的内容。而不会输出第一个括号的捕获内容,因为第一个括号的捕获内容不会保存!!编号0依然是整个正则表达式匹配的内容。
括号的用途:反向引用
- 作用:在表达式的某一部分,动态重复之前的子表达式所匹配的文本。
- 形式:”\1” 其中的1为捕获分组的编号。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li12 {
public static void main(String[] args) {
String [] string=new String[]{"<h1>呵呵</h1>","<h1>123</h2>"};
String rex="<(\\w+)>[^<]+<(/\\1)>";
Pattern pattern=Pattern.compile(rex);
for(String str:string){
Matcher matcher=pattern.matcher(str);
if(matcher.matches()){
System.out.println("字符串:"+"\""+str+"\""+"匹配\""+rex+"\"");
}else{
System.out.println("字符串:"+"\""+str+"\""+"不匹配\""+rex+"\"");
}
}
}
}
运行结果:
字符串:"<h1>呵呵</h1>"匹配"<(\w+)>[^<]+<(/\1)>" 字符串:"<h1>123</h2>"不匹配"<(\w+)>[^<]+<(/\1)>"
例子:去掉重复单词
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li13 {
public static void main(String[] args) {
One();
System.out.println();
Two();
}
private static void Two() {
String string="hello hello";
String rex="((\\w+)\\s+\\2)";
Pattern pattern=Pattern.compile(rex);
Matcher matcher=pattern.matcher(string);
System.out.println("字符串:"+string);
System.out.println("去掉后:"+matcher.replaceAll("$2"));//美元符号可视为到如上所述已捕获子序列的引用
}
private static void One() {
String string="java java";
String rex="(\\w+)\\s+\\1";
System.out.println("字符串:"+string);
System.out.println("去掉后:"+string.replaceAll(rex,"$1"));//美元符号可视为到如上所述已捕获子序列的引用
}
}
运行结果:
字符串:java java
去掉后:java
字符串:hello hello
去掉后:hello
到了这个阶段,我想读者也有一定能力了。来看看这个文章:
锚点
- 作用:规定匹配的位置。
- 形式: “\b”单词分界符锚点。
- 单词分界符的意思是划分单词和符号之间的界限。注意:这些符号还包括换行、空格、制表符、回车符。当然读者不要想多了,符号就只有空格那几个,符号还包括中文的符号和英文的符号如”!”,”!”,英文感叹号,中文感叹号!!!等,你所
知道的一切符号!!!
例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li15 {
public static void main(String[] args) {
String [] strings=new String[]
{"我爱 java ","我爱 html5 ","我爱 \"java\"","我爱 javase"
};
String rex="\\bjava\\b";
Pattern pattern=Pattern.compile(rex);
for(String str:strings){
Matcher matcher=pattern.matcher(str);
if(matcher.find()){
System.out.println("字符串:["+str+"]有");
}else{
System.out.println("字符串:["+str+"]没有");
}
System.out.println();
}
}
}
运行结果:
字符串:[我爱 java ]有
字符串:[我爱 html5 ]没有
字符串:[我爱 "java"]有
字符串:[我爱 javase]没有
注意事项:
- \b表示单词分界符,要求一侧是单词字符,另一侧是非单词字符。
- 单词字符通常是指英文字符、数字字符和中文。
- 非单词字符通常指的是各种标点符号和空白字符。
- 如果上面这三条注意事项不是很明白,可以看这篇博客详解正则表达式中的\B和\b
锚点二
- “^” 匹配一行的开头(有可能变化),但是在没有设置匹配模式的情况下(即默认情况下),它是匹配整个字符串的开头和\A一样。
- “$” 匹配一行的末尾(有可能变化)但是在没有设置匹配模式的情况下(即默认情况下),它是匹配整个字符串的结尾和\Z一样。
- “\A” 匹配整个字符串的开头
- “\Z” 匹配整个字符串的末尾
- 如果想要 “^”和 “$”在一整段字符串中匹配逻辑行的开头或者结尾的话,需要修改匹配模式。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class li16 {
public static void main(String[] args) {
String[] strings = new String[] { "start "," start "," end "," end" };
String[] regexes = new String[] { "^start","\\Astart","end$","end\\Z"};
for (String str : strings) {
for (String regex : regexes) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if(m.find()) {
System.out.println("\"" + str
+ "\" can be matched with regex \"" + regex
+ "\"");
}
else {
System.out.println("\"" + str
+ "\" can not be matched with regex \"" + regex
+ "\"");
}
}
System.out.println("");
}
}
}
运行结果:
"start " can be matched with regex "^start"
"start " can be matched with regex "\Astart"
"start " can not be matched with regex "end$"
"start " can not be matched with regex "end\Z"
" start " can not be matched with regex "^start"
" start " can not be matched with regex "\Astart"
" start " can not be matched with regex "end$"
" start " can not be matched with regex "end\Z"
" end " can not be matched with regex "^start"
" end " can not be matched with regex "\Astart"
" end " can not be matched with regex "end$"
" end " can not be matched with regex "end\Z"
" end" can not be matched with regex "^start"
" end" can not be matched with regex "\Astart"
" end" can be matched with regex "end$"
" end" can be matched with regex "end\Z"