参考:
http://yimi128.iteye.com/blog/1436659 https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1700215?fr=aladdin
- 元字符
易混淆的几个元字符
. 表示除了\n \t之外的字符
\w 表示字母,数字,下划线(平时做密码的字符类型)
\W 匹配任何非单词字符 = [^0-9a-zA-Z_] //注意:非是加到中括号里的
\s 匹配不可见字符 \n \t \r
\S 匹配任何可见字符 = [^\n\t\r\f\v]
- 正则表达式的非贪婪匹配
默认是贪婪匹配
但是
元字符 ? 紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。
非贪婪模式会尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
例1,对于字符串“oooo”,“o+”将尽可能多的匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少的匹配“o”,得到结果 [‘o’, ‘o’, ‘o’, ‘o’]
例2,在匹配html中的<a href="www.baidu" name="NAME">aaabbb</a>
时,应该考虑到非贪婪匹配和多处的不可见字符空格问题
<a[\S\s]*href="([\S\s]*?)"[\S\s]*>(\w*)</a>
则可成功匹配;group(1)和group(2)
上述正则表达式用到\s,\S,\w以及非贪婪匹配
<a[\S\s]*href="([\S\s]*)"[\S\s]*>(\w*)</a>
若在[\S\s]后没有非贪婪标志则匹配出:www.baidu” name=”NAME,会贪婪的匹配到最后一个引号为止
注意:(\w)*
此时只是匹配b;(\w*)
才可成功匹配aaabbb
- 后向引用
使用”\数字”代表前面某个子模式的匹配内容,下面代码match1和match2均有体现
附:
Java中
Matcher match1=Pattern.compile("<h([1-6])>.*?</h\\1>") .matcher("<h1>This is a valid header</h1><h2>This is not valid.</h3>");
Matcher match2=Pattern.compile("(\\w)\\1").matcher("abbbbc");
boolean flag=match1.matches();//只有当字符串完全匹配该正则表达式时,该函数返回 true;
if(match1.find()){//一般用 match.find()查找是否含有匹配的子串
System.out.println(match1.group(1));//1
System.out.println(match1.group(0));//<h1>This is a valid header</h1>
}
if(match2.find()){
System.out.println(match2.group(1));//b 注意:输出的是该子模式(即括号) 匹配的内容
System.out.println(match2.group(0));//bb 注意:并没有输出 bbbb,"\1"其实表达的是原字符串的[1,2),前开后闭
}
//非贪婪模式
Matcher match3=Pattern.compile("<a[\\S\\s]*href=\"([\\S\\s]*?)\"[\\S\\s]*>(\\w*)</a>").matcher("<a href=\"www.baidu\" name=\"NAME\">aaabbb</a>");
if(match3.find()){//一般用 match.find()查找是否含有匹配的子串
System.out.println(match3.group(1));//www.baidu
System.out.println(match3.group(2));//aaabbb
}
- 非获取匹配(只匹配,不保存)
子模式(即括号中的正则)的匹配内容 不会被match保存,不能被用于上述的“后向引用”中;
//非获取匹配(只匹配,不保存)
Matcher match4=Pattern.compile("Windows (?:[\\w]+\\b)").matcher("Windows 95 and Windows 98 are the successor");
if(match4.find()){//一般用 match.find()查找是否含有匹配的子串
System.out.println(match4.group()); //Windows 95
System.out.println(match4.group(1)); //java.lang.IndexOutOfBoundsException: No group 1
}