java基础之正则表达式

        正则表达式是用来操作字符串的规则,我们可以把正则表达式看做一个模板,把字符串放到这个模板中就可以得到我们想要的样子。


一.  正则表达式的简介


1.正则表达式的概念

        正则表达式是一种规则,那么他用特定的符号来表示代码操作,这样就简化了书写,所以学习正则表达式就是学习一些特殊符号的使用,我们先来了解一下正则表达式的常用符号。

(1)字符类

        [abc]表示此位置是否含有此字符

        [^abc]表示此位置除了abc都可以接收

        [a-zA-Z]接收全部字母,不区分大小写

        [a-b[m-p]]表示可以接收a到b和M到p的字符集

        [a-z&&[^bc]]表示接收a到z但是不包含bc

        [a-z&&[^m-p]]表示接收a到z但是不包含m到p的子集

(2)预定义字符类

        .      任何字符

        \ d    数字0-9

        \D    非数字

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

        \S    非空白字符

        \w    单词字符[a-zA-Z_0-9] ,邮箱使用

        \W   非单词字符

注意点:\ 单独出现时是转义字符,而\d是一个整体,所以要写\\d,在正则中只要出现“\”在使用的时候就得写“\\”

(3)Greedy 数量词

        X?               表示X出现一次或一次也没有

        X*                表示X出现零次或多次

        X+               表示X出现一次或多次

        X{n}            表示X出现恰好 n 次

        X{n,}           表示X出现至少 n 次

        X{n,m}       表示X出现至少 n 次,但是不超过 m 次

(4) 组

        组是正则当中一个非常强大的概念,我们可以把一个表达式封装成组,就是把它放在括号当中,组是有编号的,第一个括号包装的为第一组,在这个组之后还可以继续使用这个组的结果。

        捕获组可以通过从左到右计算括号来编号。例如,在表达式 ((A)(B(C)))中,存在四个这样的组: 第一组:((A)(B(C))),第二组:(A),第三组: (B(C)),第四组: (C),利用“\\+组的编号”来表示是第几组,例如“\\1”就代表着第一组。而获取组中的内容可以使用”&”,他可以把组中的内容拿到。

2.正则表达式的使用

正则表达式可以应用于操作字符串的两个方法中,作为模板来格式化这个字符串,这两个方法分别是:

(1)匹配:matches(String regex)

返回boolean型,用规则匹配整个字符串,如果有一个不匹配就返回假。

        我们通过对一个手机号码进行校验,使用正则的匹配功能,定义一个正则表达式,把手机号码的特点用正则进行描述,然后将手机号码的字符串表现形式按此正则表达式进行匹配。

/*
 * 校验手机号
 * 1.利用键盘录入信息
 * 2.定义正则表达式,描述手机号
 * 3.利用matches方法判断手机号是否正确
 * */
public class Test1 {
	public static void main(String[] args) {
		//利用Scanner接收键盘录入手机号
		Scanner sc = new Scanner(System.in);
		while(true)
		{
			//获取录入数据
			String str = sc.next();
			//如果输入“out”程序结束不再录入
			if("out".equals(str))
				break;
			/*定义正则表达式描述手机号信息
			 * [1]指第一位必须是数字1
			 * [358]指第二位数字必须是3或5或8
			 * \\d第二位后必须是数字
			 * {9}代表第二位后必须有9位数
			 * */
			String regex = "[1][358]\\d{9}";
			//判断是录入数据是否是手机号,利用String的matches方法
			if(str.matches(regex))
			{
				System.out.println("您输入手机号正确!");
				break;
			}else
			{
				System.out.println("输入错误,请重新输入!");
			}
		}
	}
}

(2)切割:split(String regex)

返回字符串数组,用指定的正则表达式来切割字符串。

注意点:在切割中我们常用正则来切割URL路径,当我们以“\”作为切割的标准时,在定义正则表达式时要写为“\\”,因为在正则中”\”代表转义字符,所以要多加一个“\”,而URL路径中的“\\”在正则中的表现形式是“\\\\”。

public class SplitDemo2 {
	public static void main(String[] args) {
		
		split_1();
		System.out.println();
		split_2();
	}
	/*
	 * 正则切割示例1
	 * 将字符串“小宏    小蓝             小绿   小黑”按空格切割,得到文字。
	 * */
	private static void split_1() {
		//定义字符串
		String str = "小宏    小蓝             小绿   小黑";
		//定义正则,因为要按空格切,空格数目不确定使用+来表示
		String regex = " +";
		split(str,regex);
		/*
		 * 结果是:
		 * 	小宏
			小蓝
			小绿
			小黑
		 * */
	}
	
	/*
	 * 正则切割示例2
	 * 将一堆字符串按照叠词切割,例如将
	 * “heimazzxiaohongzzxiaoheizzxiaohua”
	 * 按照“zz”进行切割。利用组的概念。
	 * */
	private static void split_2() {
		
		String str = "heimazzxiaohongzzxiaoheizzxiaohua";
		//定义正则,(.)组代表任意字符,\\1代表着后一位和组是一样的内容
		String regex = "(.)\\1";
		split(str,regex);
		/*
		 * 结果是:
		 * 	heima
			xiaohong
			xiaohei
			xiaohua
		 * */
	}
	//切割打印功能函数
	private static void split(String str, String regex) {
		String[] strs = str.split(regex);
		for(String s : strs)
		{
			System.out.println(s);
		}	
	}
}

(3)替换:replaceAll(String regex,String str)

返回字符串,以指定的字符串str替换掉字符串中正则表达式regex所匹配到的内容。

class Test3
{
	public static void main(String[] args) 
	{
		//将字符串中的数字替换成数组
		String str1 = "xiaohong12adsf3321adfads";
		replaceAll(str1,"\\d","#");
		//将叠词替换成#
		String str2 = "dfasdkkyasdaalslkddddqqffea";
		replaceAll(str2,"(.)\\1+","#");
		//将重叠字母替换成单个字母:  "$1"
		String str3 = "xiaohong hhhhh xiaolv yyyy xiaolan";
		replaceAll(str3,"(.)\\1+","$1");
	}
	//替换功能函数
	public static void replaceAll(String str,String reg,String newStr)
	{
		str = str.replaceAll(reg,newStr);
		System.out.println(str);
	}
	/*
	 * 结果是:
	 * 	xiaohong##adsf####adfads
		dfasd#yasd#lslk###ea
		xiaohong h xiaolv y xiaolan
	 * 
	 * */	
}

(4)获取

        通过正则表达式把符合要求的子串从字符串中取出具体操作步骤为:

        1>将正则表达式封装成对象,把正则表达式封装成对象的类叫做Pattern,这个类是一个工具类,在这个类中有一个方法compile(String regex),他可以将指定的正则表达式封装成Pattern对象。

        2>让正则对象和要操作的字符串相关联,通过Pattern类中的matcher(CharSequence input)方法,将字符串作为参数传入matcher方法中。

        3>关联后获取正则匹配引擎,当调用matcher方法时会返回一个Matcher对象,这个Matcher就是一个匹配引擎,他具有更多的方法来操作与之匹配的字符串。

        4>启动引擎对符合规则的子串进行操作,我们可以通过Matcher的方法find()方法来将规则作用到字符串上,并进行符合规则的子串查找,然后调用group()方法来返回符合规则的子串,这样就完成了利用正则来获取指定子串。

/*
* 利用指定的规则来获取字符串中的子串
* 获取“heima nihao wo shi xiao hong wo lai le”
* 中由四位字符组成的词组
* */
public class Test4 {

	public static void main(String[] args) {
		String str = "heima nihao,wo shi xiao hong,wo lai le!";
		//定义正则,定义四字单词需要用到边界字符“\b”
		String regex = "\\b[a-z]{4}\\b";
		//把正则封装成对象
		Pattern pt = Pattern.compile(regex);
		//获取匹配引擎
		Matcher mc = pt.matcher(str);
		//将正则作用于字符串上,并进行符合规则的查找
		while(mc.find())
		{
			//取出符合规则的子串
			String ss = mc.group();
			System.out.println(ss);
		}
	}
}
/*
* 打印:
* 	xiao
	hong
* */

3.正则的弊端

        当我们需要的规则越多,定义的正则表达式就越长,这样阅读性越差,一个复杂的正则表达式让人不能一眼就看出他的作用。而且使用正则之后当输入错误无法精准的定位错误出现的原因。


二.   正则表达式的练习


1.  去掉标点和叠词

/*
 * 将以下字符串去重复和省略号
 * “我我...我我...要....学学学...编....编...程“
 * */
public class Test5 {
	public static void main(String[] args) {
		String str = "我我...我我...要....学学学...编....编...程";
		/*分析正则表达式如何定义
		 * 1.需要去省略号
		 * 2.去叠词
		 * */
		//去省略号,使用替换
		String newStr1 = str.replaceAll("[.]+","");
		System.out.println(newStr1);
		//去叠词,使用组
		String newStr2 = newStr1.replaceAll("(.)\\1+", "$1");
		System.out.println(newStr2);
	}
}
/*
 * 打印:
 * 	我我我我要学学学编编程
	我要学编程
 */

2.对IP地址进行排序

/*
 * 使用正则对一堆ip地址进行排序
 * 192.168.0.1 102.23.45.23 10.10.20.10 2.3.3.3 9.132.43.21
 * 
 * 让ip地址按照字符串自然顺序,2排到10的后面,所以要让他们每一段都是3位,
 * 即010对应002时,002就排到010的前面。
 * 思路:
	1.利用正则将每一段的ip地址前补两个0
	2.将每一段只保留3位
	3.将3位的ip地址进行排序
	4.将ip地址进行还原
 * */
public class Test6 {

	public static void main(String[] args) {
		String ip = "192.168.0.1 102.23.45.23 10.10.20.10 2.3.3.3 9.132.43.21";
		//补两个0
		String newIp1 = ip.replaceAll("(\\d+)", "00$1");
		//保留三位
		String newIp2 = newIp1.replaceAll("0*(\\d{3})", "$1");
		//将三位数的ip地址进行排序
		String[] strs = newIp2.split(" +");
		Arrays.sort(strs);
		//遍历排完序的数组,并将他们还原
		for(String s:strs)
		{
			System.out.println(s.replaceAll("0*(\\d+)", "$1"));
		}
	}
}
/*
 * 打印:
 * 	2.3.3.3
	9.132.43.21
	10.10.20.10
	102.23.45.23
	192.168.0.1
 * 
 * */

3.网页爬虫,获取网页中邮箱

           我们可以利用正则来匹配网页上的数据,来获取邮箱名,邮箱的正则表达式较为精准的是“\\w+@\\w+(\\.[a-zA-Z]+){1,3}”,这种格式获取到的邮箱绝大多数为正常的。我们来看一下如何在网页上获取邮箱:

/*
 * 建立一个网页爬虫,获取网页中的邮箱
 * 1.自定义一个URL访问网页
 * 2.获取网页中的内容
 * 3.定义正则匹配网页中信息,获取到邮箱
 * 4.将获取到的邮箱打印出来并写入本地文件中
 * */
public class Test7 {

	public static void main(String[] args) {
		PrintWriter pw = null;
		BufferedReader br = null;
		
		try {
			
			//定义输入流,将获取到的邮箱写入到本地文件
			pw = new PrintWriter(new FileWriter("e://email.txt"),true);
			//自定义客户端访问网页
			URL u = new URL("http://www.itheima.com/newhelp/393.html");
			URLConnection uc = u.openConnection();
			br = new BufferedReader(
									new InputStreamReader(uc.getInputStream()));
			String line = null;
			//定义正则用来匹配邮箱
			String regex = "\\w+@\\w+(\\.[a-zA-Z]+){1,3}"; 
			//把正则封装成对象
			Pattern p = Pattern.compile(regex);
			while((line = br.readLine())!=null)
			{
				//拿到引擎匹配当前行
				Matcher mc = p.matcher(line);
				while(mc.find())
				{
					String str = mc.group();
					System.out.println(str);
					pw.println(str);
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally
		{
			pw.close();
			try {
				if(br==null)
					br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}	
	}
}
/*
 * 打印:
 * heima@csdn.net
 * */
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值