正则表达式中的基本正则规则详解01
来源:互联网 发布:二级ms office软件 编辑:程序博客网 时间:2024/05/24 07:09
转载原文章链接:http://blog.csdn.net/marvel__dead/article/details/53364406
字符组
- 正则表达式的最基本结构之一。
- 作用:规定某个位置能够出现的字符。
- 形式:以”[…]”给出,在方括号内列出字符。或者简写字符。
- 方括号中的字符为某个位置是否出现的字符,例如[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","2","A","B","a","b","\n","\t","\r"," ","呵","!","!"}; 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","2","A","B","a","b","\n","\t","\r"," ","呵","!","!",".","。"}; 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[]{"","a","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[]{"","a","aa","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","a","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","that","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.netusername is: webmasterhostname 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.netgroup No.1 is: webmaster@itcast.netgroup No.2 is: webmastergroup No.3 is: itcast.netmatch result: webmaster@itcast.netgroup No.1 is: rgroup 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.netgroup 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"
1 0
- 正则表达式中的基本正则规则详解01
- 正则表达式中的基本正则规则详解01
- 正则表达式中的基本正则规则详解02
- 基本正则表达式规则
- 正则表达式基本规则
- 正则表达式中的规则
- 正则表达式规则,正则表达式详解
- 正则表达式基本语法规则
- 正则表达式一些基本规则
- 解读C#中的规则表达式(正则表达式)
- 解读C#中的规则表达式(正则表达式)
- 正则表达式的基本语法规则
- Python3正则表达式(一)基本语法规则
- 正则表达式基本语法详解
- 正则表达式基本语法详解
- 正则表达式基本语法详解
- 正则表达式基本语法详解
- 正则表达式基本语法详解
- MAC OSX10.12.x 使用Qt5.7出现的错误及解决方案
- 文件的基本操作-字符的读写
- 知识库--Reloader interface(47)
- sql语句 查询表中 每门课都大于80分的学生名称 根据以下三种 学习sql 中其他函数的使用
- Scala 的 yield 例子 (for 循环和 yield 的例子)
- 正则表达式中的基本正则规则详解01
- 【C#】39. 前台线程与后台线程
- java webservice soap消息请求例子
- ESP8266移植MQTT连接中移ONENET
- 10个经典的Java main方法面试题
- Collection
- 关于iptables
- http协议中的get和post
- 九宫格项目一