黑马程序员-java学习笔记-正则表达式

---------------------- 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]abc(简单类)
[^abc]任何字符,除了 abc(否定)
[a-zA-Z]azAZ,两头的字母包括在内(范围)
[a-d[m-p]]admp[a-dm-p](并集)
[a-z&&[def]]def(交集)
[a-z&&[^bc]]az,除了 bc[ad-z](减去)
[a-z&&[^m-p]]az,而非 mp[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 执行匹配操作的引擎。

只要给Patternmatcher( )方法送一个字符串就能获取一个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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值