---------------------- android培训、java培训、期待与您交流! ----------------------
正则表达式,就是用于专门操作字符串,用特定符号来表示一些代码操作,简化书写,提高编码效率。
所以我们学习正则表达式,就是要学习特定符号。
这里有个需求:对QQ号码进行校验,要取5~15位,0不能开头,只能是数字。
如果用传统方法的话,思路就是用String类中的方法组合完成操作,但是过于复杂
下面是String类操作的代码
public static void checkQQ(String qq){
int len = qq.length();//获取字符串长度
if(len>=5 && len<=15){//取5~15位
if(!qq.startsWith("0")){//判断是否是0开头
try {
long l = Long.parseLong(qq);
System.out.println(l+":正确");
}catch(NumberFormatException e){//如果不是纯数字,就好抛出异常
System.out.println(qq+":含有非法字符");
}
}else{
System.out.println(qq+":不能0开头");
}
}else{
System.out.println(qq+":长度错误");
}
}
String qq = "123k4567";
String regex = "[1-9][0-9]{4,14}";//正则表达式。
boolean b = qq.matches(regex);//判断是否符合正则表达式的描述
System.out.println(qq+":"+b);//打印到控制台
上面两段代码可以明显看出,用正则表达式去处理字符串问题要简洁快速,但是缺点也是显而易见,如果字符串定义越多,正则表达式越长,阅读性就越差。
通过查阅JDK文档,可以在java.util.regex类中查阅到详细的正则表达式的符号意义,这里列举了常用的一些符号
字符 | |
---|---|
x | 字符 x |
\\ | 反斜线字符 |
\0n | 带有八进制值 0 的字符 n (0 <= n <= 7) |
\0nn | 带有八进制值 0 的字符 nn (0 <= n <= 7) |
\0mnn | 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7) |
\xhh | 带有十六进制值 0x 的字符 hh |
\uhhhh | 带有十六进制值 0x 的字符 hhhh |
\t | 制表符 ('\u0009') |
\n | 新行(换行)符 ('\u000A') |
\r | 回车符 ('\u000D') |
\f | 换页符 ('\u000C') |
\a | 报警 (bell) 符 ('\u0007') |
\e | 转义符 ('\u001B') |
\cx | 对应于 x 的控制符 |
字符类 | |
---|---|
[abc] | a、b 或 c(简单类) |
[^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] |
Possessive 数量词 | |
---|---|
X?+ | X,一次或一次也没有 |
X*+ | X,零次或多次 |
X++ | X,一次或多次 |
X{n}+ | X,恰好 n 次 |
X{n,}+ | X,至少 n 次 |
X{n,m}+ | X,至少 n 次,但是不超过 m 次 |
正则表达式对字符串的常用操作
1, 匹配。
其实使用的就是String类中的matches方法。用正则表达式的规则去匹配字符串,有一处出错就返回false
//匹配手机号码是否正确。 手机号必须是13xxx 15xxx 18xxx
String tel = "15800001111";
String regex = "1[358]\\d{9}";
//第一个数字是1,第二个数字可以是3、5或者8,\d表示0~9的数字,这里用了双斜杠是字符转义,{9}表示后面的数字必须是9位
boolean b = tel.matches(regex);
System.out.println(tel+":"+b);
2,切割。
其实使用的就是String类中的split方法。
String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
String[] names = str.split("(.)\\1+");// str.split("\\.");
/*正则解读:按照重叠的字符进行切割,重叠的字符可以是一次或者多次
* ()表示一个组,为了可以让规则结果被重用,可以将规则封装成组,
* (.)这样用小括号包起来的规则就成为组,.表示任何字符
* 组都有编号,从1开始
* 结果被重用的意思:
* 拿上没的例子来说,先冲重叠的tttt作为标志开始切割字符串,得出zhangsan
* 然后字符串就冲切割后的字符串开始,也就是从xiaoqiang开始进行新一轮的切割
* */
for (String name : names) {
System.out.println(name);
}
3,替换。
其实使用的就是String类中的replaceAll()方法。
//把电话中间的0替换成*
String tel = "15800001111";//158****1111;
tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
/*正则解读:保留字符串前三位和后四位,将中间四位替换成*
(\d{3})()表示一个组,将字符串前三个作为一个组,后面的四位字符串同理
*/
System.out.println(tel);
4,获取。
思路分析
1)将正则规则进行对象的封装。
Pattern p = Pattern.compile("a*b");
2)通过正则对象的matcher方法字符串相关联。获取要对字符串操作的匹配器对象Matcher .
Matcher m = p.matcher("aaaaab");
3)通过Matcher匹配器对象的方法对字符串进行操作。
boolean b = m.matches();
String str = "da jia hao,ming tian bu fang jia!";
String regex = "\\b[a-z]{3}\\b";
/*正则解读:精确匹配出只有三个字母组成的字符串
\b 代表着单词的开头或结尾,也就是单词的分界处,它只匹配一个位置
[a-z]表示26个字母中任意一个
{3}总共有3个
*/
//1,将正则封装成对象。
Pattern p = Pattern.compile(regex);
//2, 通过正则对象获取匹配器对象。
Matcher m = p.matcher(str);
//使用Matcher对象的方法对字符串进行操作。
//既然要获取三个字母组成的单词
//查找。 find();
System.out.println(str);
while(m.find()){
System.out.println(m.group());//获取匹配的子序列
System.out.println(m.start()+":"+m.end());
}
这里用到了两个类:Pattern和Matcher,这两个类是再java.util.regex包中,Java的正则表达式是由java.util.regex的Pattern和Matcher类实现的。
Pattern类,正则表达式的编译表示形式,指定为字符串的正则表达式必须首先被编译为此类的实例。
Matcher类,通过解释 Pattern 对 character sequence 执行匹配操作的引擎。
只要给Pattern的matcher( )方法送一个字符串就能获取一个Matcher对象。
因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
在仅使用一次正则表达式时,可以方便地通过此类定义 matches
方法。此方法编译表达式并在单个调用中将输入序列与其匹配。语句
boolean b = Pattern.matches("a*b", "aaaaab");
等效于上面的三个语句,尽管对于重复的匹配而言它效率不高,因为它不允许重用已编译的模式。
在我们熟知的String类的mathes()方法,方法内部用的就是Pattern和Matcher两个类
我们来做一个综合的案例:网页爬虫
其实就一个程序用于在互联网中获取符合指定规则的数据,这里我们爬去网页中的邮箱地址
public static List<String> getMailsByWeb() throws IOException {
//1,读取源文件。
// BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));
URL url = new URL("http://192.168.1.100:8080/myweb/mail.html");//封装ip地址
BufferedReader bufIn = new BufferedReader(new InputStreamReader(url.openStream()));
//2,对读取的数据进行规则的匹配。从中获取符合规则的数据.
String mail_regex = "\\w+@\\w+(\\.\\w+)+";
List<String> list = new ArrayList<String>();
Pattern p = Pattern.compile(mail_regex);
String line = null;
while((line=bufIn.readLine())!=null){
Matcher m = p.matcher(line);
while(m.find()){
//3,将符合规则的数据存储到集合中。
list.add(m.group());
}
}
return list;
}
---------------------- android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net