---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
1、 正则表达式
正则表达式:符合一定规则的表达式,一般用这些规则对字符串进行操作。
特点:用一些特定的符号来表示一些代码操作,这样能简化字符串操作的书写代码。
好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则越长,阅读性越差。
2、 正则常用的符号
我们先来看以个简单的示例:
public staticvoid matches(){ String str = "832947298"; String rege = "[1-9][0-9]{4,14}"; System.out.println(str.matches(rege)); }
该示例是判断qq号码是否正确的方法,QQ号要求4到15位,首位不能为0,全数字组合。那么” [1-9][0-9]{4,14}”便是匹配规则,即正则表达式,第一个[1-9]内容表示第一个数字在1-9之间,[0-9]表示0-9之间,紧随其后的{4,14}表示前一数字规则出现的次数或说重复的次数为4-14。那么str.matches(rege)语句表示用该正则表达式对str字符串进行检查,返回boolean。
查API手册我们例举一些常用的符号及其含义:
字符类:(包括数字)
用引号包围的都是字符,包括数字,上述QQ号码检测便是一个示例。
[abc]
a、b 或 c(3者任意一个)
[^abc]
任何字符,除了 a、b 或 c
[a-zA-Z]
a-z 或 A-Z,两头的字母包括在内
[a-d[m-p]]
a-d 或 m-p:[a-dm-p](并集)
[a-z&&[def]]
d、e 或 f(交集)
[a-z&&[^bc]]
a-z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]]
a-z,而非 m-p:[a-lq-z](减去)
预定义字符类:(简化用,一些符号规则的替代)
.
任何字符
\d
数字:[0-9]
\D
非数字: [^0-9]
\s
空白字符:[ \t\n\x0B\f\r]
\S
非空白字符:[^\s]
\w
单词字符:[a-zA-Z_0-9]
\W
非单词字符:[^\w]
像[a-zA-Z_0-9]这样写起来很长,用\w代替即可,那么上面QQ号码检测的"[1-9][0-9]{4,14}"规则便可改写成"[1-9]\\d{4,14}",这里需注意,字串中’\d’的表示需在前家以个反斜杠转义,即‘\\d’才能读出\d。
边界匹配器:
^
行的开头
$
行的结尾
\b
单词边界
\B
非单词边界
\A
输入的开头
\G
上一个匹配的结尾
\Z
输入的结尾,仅用于最后的结束符(如果有的话)
\z
输入的结尾
后面的正则表达式获取子字串功能中有示例。
Greedy数量词:(其中X代表一种规则)
X?
X,一次或一次也没有
X*
X,零次或多次
X+
X,一次或多次
X{n}
X,恰好 n 次
X{n,}
X,至少 n 次
X{n,m}
X,至少 n 次,但是不超过 m 次
如”[abc]+”表示字符串由abc三字母组成,至少有一个。X即为规则[abc]。
3、 正则表达式的具体功能
(1) 匹配
主要是利用String的matches方法,返回boolean,一般用于字符串的检测。
像上述的QQ号码检测。
(2) 切割
主要利用String的split方法,提供一个切割规则,返回String数组。
示例:
//实现体 public static void splitDemo(String str, String reg){ String[] strs = str.split(reg); for(String s : strs){//迭代输出切割后部分 System.out.println(s); } } //调用语句,同时包括了切割规则,需反斜杠转义‘\\’,一根一个 splitDemo("c:\\file\\a.txt","\\\\"); splitDemo("a***c*d**e****f","[*]+");//按‘*’切,可多个
(3) 替换
按正则表达式进行替换,看示例:
//参数str源串,rege正则表达式,newStr要替换的字串 public static void replaceDemo(String str, String rege, String newStr){ str = str.replaceAll(rege, newStr); System.out.println(str); } //调用 replaceDemo("a8276348bcd876876efg","\\d{5,}", "*");//数字替换成*
(4) 获取
将字符串中的符合规则的子串取出。
操作步骤:
(a) 将正则表达式封装成Pattern对象。
(b) 让正则对象和要操作的字符串相关联。
(c) 关联后,获取正则匹配引擎(Matcher对象)。
(d) 通过引擎对符合规则的子串进行操作,比如取出。
public static void getDemo(){ String str = "ming tian jiu yaofang jia le , da jia 。"; //其中\\b便是单字母边界匹配符 String rege ="\\b[a-z]{3}\\b"; //将规则封装成对象 Pattern p = Pattern.compile(rege); //让正则对象和要作用的字符串相串联,获取匹配器对象。 Matcher m = p.matcher(str); //将规则作用在字符串上,并用find进行子串的查找 while(m.find()){ //查找一个子串,用一次find,用group()获取该子串 System.out.println(m.group()); } } /*结果为: jiu yao jia jia */
其中"\\b[a-z]{3}\\b"正则表达式中用到了单字母边界符,[a-z]{3}会在以字母开头和结尾的连续字母串中匹配。所以"ming"整串不符合,而"yao"符合。
其实String中的maches方法就是由Pattern和Matcher的对象来完成的,只不过String的matcher方法进行功能封装,用起来简单,但功能单一。
4、 组的运用
为了让规则的结果被重用,可以将规则封装成一个组,用()完成。
组的出现都有编号,从1开始,想要使用已有的组可以通过\n(n就是组的编号)的形式来获取。
那么()括号为组,可自动编号,括号里为规则,
如(.)\1,第一组,“(.)\\1”,那么((())())就有4组,从左括号开始数。
示例:(函数实现体replaceDemo()在上面已给出,这里不重复,只做调用,重点看正则表达式)
(a)调用,替换重叠字符串为&
replaceDemo("abbbcddeffghhk","(.)\\1+", "&");
在” (.)\\1+”正则表达式中()内为点,表示任意单个字符,\1为第一组,当然这里只有一组,\1+则为第一组重复一次或一次以上,符合该规则的就用‘&’替换,结果为a&c&e&g&k。
(b)重叠字符串替换成单个字母
replaceDemo("abbbcddeffghhk","(.)\\1+", "$1");
其中$表示取前面规则的数据,$1为取第一组数据做参考,(.)会获取单个字母,那么如果获取bbb满足了正则表达式"(.)\\1+",其单个字母为b,替换要求为$1,则会将bbb替换成b,最终结果为abcdefghk。
5、 正则应用(网页爬虫)
网页爬虫,也叫网页蜘蛛,能在网页源码中获取符合要求的数据,以下是一个获取网页中的邮箱地址,并输出到控制台的例子。其中的网站地址为测试地址,该地址需有效,且能连接服务器,若网页中有符合邮箱地址格式的字段,便会被获取。直接看代码吧:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HtmlEmaiDemo { public static void main(String[] args) throwsException{ //输入连接正服务器的网址 getMails("http://zhidao.baidu.com/question/262256558.html"); } public static void getMails(String strUrl)throws Exception{ //创建URL对象 URL url = new URL(strUrl); //获取远程连接 URLConnection conn =url.openConnection(); //获取资源流 BufferedReader bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream())); String strLine = null; //定义筛选邮箱地址的正则表达式 String mailreg ="\\w+@\\w+(\\.\\w+)+"; //创建Pattern对象 Pattern p = Pattern.compile(mailreg); while((strLine =bufIn.readLine())!=null){ //获得匹配器 Matcher m = p.matcher(strLine); //根据匹配器查找 while(m.find()){ //获取匹配字段 System.out.println(m.group()); } } } }
---------------------- ASP.Net+Android+IO开发S、 .Net培训、期待与您交流! ----------------------