黑马程序员_正则表达式

------- android培训java培训、期待与您交流! ----------

 

一.概述

    1.概念:符合一种规则的表达式。

    2.作用:用于操作字符串。

   3.特点:用一些特定的符号来表示一些代码操作,简化书写。

   4.好处:可以简化对字符串的复杂操作。

    5.弊端:符号定义越多,正则越长,阅读性越差。

 

二.常见符号的定义

   1.字符

         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 的控制符

 2.字符类

     [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&&[^n-p]] a到z,而非n到p:[a-lq-z](减去)

  

 3. 预定义字符类

       \d     数字[0-9]   注意:在java中\\成对出现  \\d

       \D    非数字[^0-9]

       \s    空白字符: [ \t\n\x0B\f\r]

       \S    非空白字符: [^\s]

       \w    单词字符 :  [a-zA-Z_0-9]

       \W   非单词字符:  [^\w]

  

 4. Greedy数量词

       X?    X,一次或一次也没有

       X*   X, 零次或多次

      X+   X,一次或多次

     X{n}   X,恰好 n

     X{n,}   X,至少 n

    X{n,m}  X,至少 n 次,但是不超过 m 

   

  5.边界匹配器

           ^               行的开头

           $                行的结尾

          \b                单词边界

          \B                非单词边界

          \A                输入的开头

          \G              上一个匹配的结尾

          \Z               输入的结尾,仅用于最后的结束符(如果有的话)

          \z               输入的结尾

 

  6.组和捕获

    捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:  

          ((A)(B(C)))

           \A

         (B(C))

          (C)

      组零始终代表整个表达式。

      以 (?) 开头的组是纯的非捕获组,它不捕获文本,也不针对组合计进行计数。

三.正则表达式的具体操作功能

   1.匹配:

     String类中的matches()方法,用规则匹配整个字符串,只要有一处不符合规则,返回false。

   代码:

public class MatchesDemo {

	public static void main(String[] args) {
		// 校验qq
		checkQQ_1();// 普通方式
		checkQQ_2();// 使用正则表达式
		
		// 校验手机号码
		checkPhoneNumber("18215160718");
		
		// 校验邮箱
		checkMail("12345@qq.com");
	}

	/*
	 * 对QQ号码进行校验 要求:5~15 0不能开头,只能是数字
	 */
	// 普通校验方式,使用了String类中的方法,进行组合完成了需求。但是代码过于复杂。
	public static void checkQQ_1() {
		String qq = "1882345a0";

		int len = qq.length();

		if (len >= 5 && len <= 15) {
			if (!qq.startsWith("0"))// Integer.parseInt("12a");NumberFormatException
			{
				try {
					long l = Long.parseLong(qq);
					System.out.println("qq:" + l);
				} catch (NumberFormatException e) {
					System.out.println("出现非法字符.......");
				}
			} else {
				System.out.println("不可以0开头");

			}
		} else {
			System.out.println("长度错误");
		}
	}

	// 使用正则表达式
	public static void checkQQ_2() {
		String qq = "12345";
		// 定义规则
		String regex = "[1-9][0-9]{4,14}";
		// 调用matches()方法
		boolean flag = qq.matches(regex);
		if (flag) {
			System.out.println("qq" + "是合法的!");
		} else {
			System.out.println("qq不合法");
		}
	}

	/*
	 * 校验手机号码
	 */
	public static void checkPhoneNumber(String phoneNumber) {
		// 定义规则,校验手机号码
		String regex = "1[3458]\\d{9}";
		boolean flag = phoneNumber.matches(regex);
		if (flag) {
			System.out.println("手机号正确");
		} else {
			System.out.println("手机号码非法");
		}

	}

	/*
	 * 校验邮箱地址
	 */
	public static void checkMail(String mail) {
		// 定义规则,校验邮箱
		String mailRegex = "\\w+@\\w+\\.[a-zA-Z]{2,4}";
		boolean flag = mail.matches(mailRegex);
		if (flag) {
			System.out.println("邮箱格式正确");
		} else {
			System.out.println("邮箱格式错误");
		}

	}

}

  2.切割:

  String类中的split()方法。

  代码:

  /*
 * 正则表达式的第二个功能:
 * 切割
 * String  split()
 * */
public class SplitDemo {
     public static void main(String[] args) {
    	 split("zhangsan.lisi.wangwu","\\.");
    	 split("c:\\abc\\a.txt","\\\\");
    	/* 按照叠词完成切割*/
 		 split("erkktyqqquizzzzzo","(.)\\1+");
	}
     
  // 按照正则表达式切割
 	public static void split(String str, String reg) {
 		// String reg1 = " +";//按照多个空格来进行切割
 		// String reg2="\\.";//按 .切割
 		// String reg3="(.)\\1+";//按照叠词切割
 		String[] arr = str.split(reg);
 		System.out.println(arr.length);
 		for (String s : arr) {
 			System.out.println(s);
 		}
   }
}

  

   按照叠词完成切割:

        为了可以让规则的结果被重用,可以将规则封装成一个组。用()完成。组的出现都有编号。

       编号从1开始。 想要使用已有的组可以通过 \n(n就是组的编号)的形式来获取。 

   3.替换

       String类中的replaceAll( String regex, String str); 

       如果regex中定义了组,可以在第二个参数中通过$符号获取正则表达式中已有的组。

  代码:

/*
 * 正则表达式的第三个功能:
 * 替换
 * String  replaceAll();
 * 
 * */
public class ReplaceDemo {
 
	public static void main(String[] args) {
		String str = "wer1389980000ty1234564uiod234345675f";
		//将字符串中的数字替换成#。
		replace(str,"\\d{5,}","#"); 
		
		String str2 = "erkktyqqquizzzzzo";
		//将重叠的字符替换成单个字母。zzzz->z   $1表示获取组1
		replace(str2, "(.)\\1+", "$1");
     
	}
	
	public static void replace(String str, String reg, String newStr) {
		
		str = str.replaceAll(reg, newStr);
		System.out.println(str);
	}

}

   4.获取

     将字符串中符合规则的子串取出。

   步骤:

     将正则表达式封装成对象。

     让正则对象和要操作的字符串相关联。

     关联后,获取正则匹配引擎。

     通过引擎对符合规则的字符串进行操作。

  代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*正则表达式的第四个功能。
 *获取:将字符串中的符合规则的子串取出。
 **/
class RegexDemo2 {
	public static void main(String[] args) {

		String str = "ming tian jiu yao fang jia le ,da jia。";
		System.out.println(str);
		String reg = "\\b[a-z]{4}\\b";
		// 将规则封装成对象
		Pattern p = Pattern.compile(reg);
		// 让正则对象和要作用的字符串相关联。获取匹配器对象
		Matcher m = p.matcher(str);

		// System.out.println(m.matches());//其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。
		// 只不过被String的方法封装后,用起来较为简单。但是功能却单一。

		// boolean b = m.find();//将规则作用到字符串上,并进行符合规则的子串查找。
		// System.out.println(b);
		// System.out.println(m.group());//用于获取匹配后结果。

		// System.out.println("matches:"+m.matches()); //false;

		while (m.find()) {
			System.out.println(m.group());
			System.out.println(m.start() + "...." + m.end()); // 包含头,不包含尾
		}
	}
}

   功能的选择:

    如果只想知道该字符串是对是错------匹配。

    如果将已有的字符串变成另一个字符串------替换。

    想要按照自定义的方式将字符串变成多个字符串------切割(获取规则以外的字符串)。

    想要拿到符合要求的字符串子串-----获取。

 

四.练习

  代码:

   import java.util.TreeSet;

class RegexText {
	public static void main(String[] args) {
		test();
		sort();
	}

	/*
	 * 需求: 将下列字符串转成:我要学编程.
	 * 
	 *  将已有字符串变成另一个字符串。使用 替换功能。 
	 *     1 可以先将 . 去掉。 
     *     2 在将多个重复的内容变成单个内容。
	 */

	public static void test() {
		String str = "我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程";

		//去掉. 
		str = str.replaceAll("\\.", "");
		System.out.println(str);
        
		//去掉重复的内容
		str = str.replaceAll("(.)\\1+", "$1");
		System.out.println(str);

	}

	/*
	 * 需求:对邮件地址进行校验。
	 */

	public static void checkMail() {
		String mail = "abc12@sina.com";

		mail = "1@1.1";

		String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";// 较为精确的匹配。
		reg = "\\w+@\\w+(\\.\\w+)+";// 相对不太精确的匹配。

		// mail.indexOf("@")!=-1

		System.out.println(mail.matches(reg));
	}

	/*
	 * 192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30
	 * 将ip地址进行地址段顺序的排序。
	 * 
	 * 
	 *   还按照字符串自然顺序,只要让它们每一段都是3位即可。 
	 * 1,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位。
	 * 2,将每一段只保留3位。这样,所有的ip地址都是每一段3位。
	 */

	public static void sort() {
		String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
		ip = ip.replaceAll("(\\d+)", "00$1");
		System.out.println(ip);

		ip = ip.replaceAll("0*(\\d{3})", "$1");
		System.out.println(ip);

		String[] arr = ip.split(" ");
		TreeSet<String> ts = new TreeSet<String>();// 排序用Arrays.sort() 也可以

		for (String s : arr) {
			ts.add(s);

		}
		for (String s : ts) {
			System.out.println(s.replaceAll("0*(\\d+)", "$1"));//把每段前面多余的0替换掉    
		}
	}

}

五.网页爬虫(蜘蛛)

    是一个功能,用于搜集网络上的指定信息 

  代码:

import java.io.*;
import java.util.regex.*;
import java.net.*;

/*
 网页爬虫(蜘蛛)   
 */
class RegexText2 {
	public static void main(String[] args) throws Exception
	{    
		
		getMails();
		getMails_1();
	}
	//获取网页中的邮箱地址
	public static void  getMails_1() throws Exception
	{   //URL
		URL url=new URL("http://127.0.0.1:8080/myweb/mail.html");
		//获取连接器
		URLConnection conn=url.openConnection();
		//创建流
		BufferedReader bufIn=new BufferedReader(new InputStreamReader(conn.getInputStream()));
		
		String line=null;
		//定义正则表达式
		String mail="\\w+@\\w+(\\.+\\w+)+";
		//将正则表达式封装成对象
		Pattern p=Pattern.compile(mail);
		
		while((line=bufIn.readLine())!=null)
			
		{
			//获取匹配器引擎
			Matcher m=p.matcher(line);
			while(m.find())//查找
			{
				System.out.println(m.group());//打印匹配后的结果
			}
		}
	}	
	
	
	// 获取文本中的邮箱地址
	// 使用获取功能  Pattern Matcher
	public static void getMails() throws Exception
	{   //创建流,并关联文件
		BufferedReader bufr=new BufferedReader(new FileReader("E:\\Eclipse_workspace\\javaday25\\src\\day25\\mail.txt"));	
		String line=null;
		//定义正则表达式
		String mail="\\w+@\\w+(\\.+\\w+)+";
		//将正则表达式封装成对象
		Pattern p=Pattern.compile(mail);
		while((line=bufr.readLine())!=null)
		{
			//获取匹配器引擎
			Matcher m=p.matcher(line);
			while(m.find())//查找
			{
				System.out.println(m.group());//打印匹配后的结果
			}
		}	
	}
}



 


 

------- android培训java培训、期待与您交流! ----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值