javase_24(正则表达式的学习)

 

正则表达式:符合一定规则的表达式.

作用:用于专门操作字符串

特点:用于一些特点的符号来表示一些代码的操作,这样的简化书写.

所以学习正则表达式,就是在学习一些特殊符号的应用..

好处:可以简化对字符串的复杂处理

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

作用:用于专门操作字符串

特点:用于一些特定的符号来表示一些代码的操作,这样就简化书写.

学习正则表达式,就是在学习一些特殊符号的作用,.

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

弊端:符号定义越多,正则越长,阅读新越差

具体的操作:

1,匹配:String matches方法.用正则表达式匹配整个字符串,只要有一处不匹配,都会返回false;

2,切割:String split()方法,String[]arr 

3,替换:String replaceAll(regex,"*")如果regex中有定义组,可以在第二个参数中通过$符号来获取正则表达式已经有的组.

String str = str1.replaceAll("(.)\\1+","$");//获取已经有了的正则表达式.


 

对该QQ号码进行效验:

条件:要求1-15位之间,不能以0开头.  以下用到非正则表达式:

这种方式使用到了String类中的方法,进行了组合的需求,但是代码过于复杂.

package com.javami.kudyDemo.Regex;

public class RegexDemo
{
	public static void main(String[]args)
	{
		String qq = "9496234567a";
		Check_qq(qq);
	}

	/*
	 * 第一条件: QQ号码的长度  大于 5 并且小于15
	 * 第二条件:判断是否为零开头.如果为零开头.转换成long类型.. 如果发生异常.代表转换不成功.那么该数字就是为零开头啦.
	 */
	private static void Check_qq(String qq)
	{	
		int len = qq.length();//获取QQ的长度
		if(len>=5&&len<=15)
		{
			if(!qq.startsWith("0")) //如果不是零开头的
			{
				try
				{
					Long l = Long.parseLong(qq);//如果转换不成功.代表异常出现
					System.out.println("qq号码为:"+l);
				}catch(NumberFormatException e)
				{
					System.out.println("出现非法的字符");
				}
			}else
			{
				System.out.println("数字不能为开头");
			}
		}else
		{
			System.out.println("QQ的长度不够,长度为:"+len);
		}
	}
}


 

第二种方法:使用到了正则表达式

System.out.println("\\d"); 在java的语言中,\\ 代表一个..
	private static void Check_qq2(String qq)
	{
		String regex = "[1-9]\\d{4,15}"; //由于java中的\\代表一个\
		//表达式:第一个数字  为1-9   \\d至少1+4个,并且少于15个而且是数字的
		boolean flog = qq.matches(regex);
		System.out.println(flog);
	}


 

匹配:

手机号码只有:

13***

15***

18***

	private static void Check_Number(String number)
	{	
		String regex = "1[358]\\d{9}";
		boolean flog = number.matches(regex);
		System.out.println(flog);
	}


 

切割的用法:

对空格进行分隔

	String someName = "张三   李四             王五";
	private static void splitDemo(String someName)
	{
		String regex = " +"; //有一个空格 或者多个空格
		String [] arr = someName.split(regex);
		for(String s : arr)
		{
			System.out.println(s);
		}
	}


 

String demo = "c:\\abc\\cde";\ 对\\进行切割,注意:\\必须要成对的出现

	private static void splitDemo2(String demo)
	{
		String regex = "\\\\";
		String[] arr = demo.split(regex);
		for(String s : arr)
		{
			System.out.println(s);
		}
	}


 

对多个点进行分隔:

String demo3 = "zhangsan.....lisi....wangwu";
	//以.号进行分隔
	private static void splitDemo3(String demo3)
	{
		String regex = "\\.+"; //一个.或者多个.的地方进行切割
		String[]arr = demo3.split(regex);
		for(String s : arr)
		{
			System.out.println(s);
		}
		
	}


 

对叠词进行操作:

		String demo4 = "dasdasqqsvcvxcvxddvccxdddccc";
		splitDemo4(demo4);
	/*
	 * 按照叠词	完成切割,为了可以让规则的结果重用 可以让规则封装成一个组,用()来完成
	 * 组的出现编号,
	 * 从1开始,想要使用自有的组
	 * \n(n)代表编号的形式来获取
	 *
	 */
	private static void splitDemo4(String demo4)
	{
		String regex = "(.)\\1+";
		//.代表叠词.封装成一个组,封装成组是为了重用
		//重用第一组的内容,但是这个还是代表了重要第二个叠词的位置的.所以我们要+
		//+代表了所有的叠词  ,第三个 ...第四个..
		String []arr = demo4.split(regex);
		for(String s :arr)
		{
			System.out.println(s);
		}
		System.out.println("叠词的操作..");
	}


 

"(.)\\1+"

代表叠词 重用组的内容 多个.

package com.javami.kudyDemo.Regex;

public class ReplaceAllDemo
{
	public static void main(String[]args)
	{
		String line = "wer1389980000ty1234564uiod234345675f";
		//对5位数字以上的进行切割.有重复的,所以我们需要用到组
		ReplaceAllShow(line);
		String str1 = "erkktyqqquizzzzzo";//将叠词替换成$.  //将重叠的字符替换成单个字母。zzzz->z
		RepalceAllShow2(str1);
	}
	
	/*
	 * 将叠词替换成*号
	 */
	private static void RepalceAllShow2(String str1)
	{	
		String regex = "(.)\\1+";
		//叠词,重复第一组.多个叠词
		String str = str1.replaceAll(regex,"*");
		System.out.println(str);
		//String str = str1.replaceAll("(.)\\1+","$");//获取已经有了的正则表达式.
		
	}
	
	/*
	 * 把叠词替换成#号
	 */
	private static void ReplaceAllShow(String line)
	{
		String regex = "\\d{5,}";
		//把数字刚好为5个的替换成#号
		String strLine = line.replaceAll(regex, "#");
		System.out.println(strLine);
	}
}


 

第四个功能:(主要内容.等明天也要复习)

获取:将字符串中的符合规则的字串取出.

操作步骤:

1,将正则表达式封装成对象

2,让正则对象和需要操作的字符串进行关联

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

4,通过引擎对符合规则的子串进行操作,比如取出.

package com.javami.kudyDemo.Regex;

import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexDemo2
{
	public static void main(String[]args)
	{
		String str = "ming tian jiu yao fang jia le ,da jia。";
		System.out.println(str);
		//以单词作为边界  a-z 必须是为4个的 \\b结尾
		String regex = "\\b[a-z]{4}\\b";
		
		//将规则封装成对象
		Pattern p = Pattern.compile(regex);//封装成对象
		//让正则表达式和对作用的字符串进行关联,获取匹配器对象.
		Matcher m  = p.matcher(str);
		//System.out.println(m.matches());//是否匹配.
		/*
		 * 其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的.
		 * 只不过String 方法封装后,用起来比较简单.但是功能单一.只能是boolean
		 */
		//m.find();
		//System.out.println(m.find());//第一个是啊.
	//	System.out.println(m.group());//获取到匹配过的内容
		
		//由于匹配过的内容就再也不匹配了,好像一个迭代器
		while(m.find())
		{
			System.out.println(m.group());
			System.out.println(m.start()+"......"+m.end());
			//可以看出匹配的索引位置 0 - 4算左边,但不算右边
		}
	}
}


 

题目的内容,重要...

package com.javami.kudyDemo.Regex;

import java.util.TreeSet;

public class Demo
{
	public static void main(String[]args)
	{
		String mail = "my_kudy@live.cn";
		getMail(mail);
		Test_1();
		Test_2();
	}
	
	
	/*
	需求:
	将下列字符串转成:我要学编程.
	
	到底用四种功能中的哪一个呢?或者哪几个呢?
	思路方式:
	1,如果只想知道该字符是否对是错,使用匹配。
	2,想要将已有的字符串变成另一个字符串,替换。
	3,想要按照自定的方式将字符串变成多个字符串。切割。获取规则以外的子串。
	4,想要拿到符合需求的字符串子串,获取。获取符合规则的子串。
	*/
	private static void Test_1()
	{
		String str = "我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程";
		//可以把.号替换成""字符串,但是也必须要把重复的内容去掉
		String regex = "\\.+";
		String line = str.replaceAll(regex, "");
		System.out.println(line);
		//将重复的内容变成单个,叠词可以有一个.替换成叠词的一个
		String regex2 = "(.)\\1+";//注意\\.为.符号 (.)代表叠词的一组  ,复用一组.这一组出现的叠词可以有多个
		System.out.println(line.replaceAll(regex2,"$1"));
		//$1这个叠词的里面的内容  我  要 学  编  程  叠词里面的第一个内容就是 "我"
		//.号是叠词的概念  $1叠词的第一个内容
		
	}

	//对邮件进行效验
	private static void getMail(String mail)
	{
		String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9-]+(\\.[a-zA-Z]+)+";//+这个组可以有多个
		//a-z和数字前面  可以有多个 @代表一个 ,最后一个的解释,这部分内容可以有一个.但是.只能有一个.这个组还可以有多个
		boolean b = mail.matches(regex);
		System.out.println(b);
	}

	/*
	192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30
	将ip地址进行地址段顺序的排序。
  */
package com.javami.kudyDemo.MyMap;

import java.util.TreeSet;

public class IPDemo
{
	public static void main(String[]args)
	{
		String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
		Test_ip(ip);
	}
	
	private static void Test_ip(String ip)
	{
		String regex = "(\\d+)"; //代表-->可以有多个数字的地方,咱们从前面补零
		//1.替换,前面补零
		ip = ip.replaceAll(regex, "00$1");
		System.out.println(ip);
		ip = ip.replaceAll("0*(\\d{3})", "$1");
		//2.零可以有多个,但是数字最多只有3个的地方替换成  之前$1的内容,而之前$1的内容是 : 比喻: 00192  192  
		System.out.println(ip);
		//注意这个问题!
		
		String arr[] = ip.split(" +");//出现空格或者多个空格的地方分隔
		TreeSet<String> ts = new TreeSet<String>();
		for(String e : arr)
		{
			ts.add(e);
		}
		
		System.out.println("结果出来啦:");
		//通过排序后的结果-->把零去掉
		for(String e : ts)
		{
			String line = e.replaceAll("0*(\\d+)", "$1");
			System.out.println(line);
		}
		/*
		 * 零可以有多个. 数字可以有多个的地方.假设
		 * 002.002.002.002
		 * 第一个条件成立, 0 是有了2个  2只有一个 ,那么就替换成  第一组的内容.第一组里面只有一个2
		 * 008.109.090.030
		 *第一个:条件成立  所以为8  第二个 不成立
		 *第三个:0有一个.后面的有多个 所以为90
		 *.哈哈.懂了不..yes
		 */
	}
}

网页的爬虫:
将正则表达式封装成对象.
循环读取一行的内容.将正则表达式与之关联,迭代符合条件的内容.


服务器:
package com.javami.kudyDemo.MyMap;

import java.net.ServerSocket;
import java.net.Socket;

public class RegexDemo3
{
	public static void main(String[]args)
	{
		ServerSocket ss = null;
		try
		{
			ss = new ServerSocket(8888);
			while(true)
			{
				Socket socket = ss.accept();
				new Thread(new ThreadServer(socket)).start();
			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}
多线程实现的:
package com.javami.kudyDemo.MyMap;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ThreadServer implements Runnable
{

	Socket socket;
	public ThreadServer(Socket socket)
	{
		this.socket = socket;
	}

	@Override
	public void run()
	{
		try
		{
			InputStream ips = socket.getInputStream();
			OutputStream ops = socket.getOutputStream();
			Thread.sleep(100);
			int len = ips.available();
			byte[] buf = new byte[len];
			ips.read(buf);
			String info = new String(buf,0,len);
			String firstName = info.substring(0, info.indexOf("\r\n"));
			//从第零个获取到换行的地方
			String[]arr = firstName.split(" ");
			String urlName = arr[1];
			File file = new File("src/MyMail"+urlName);
			if(!file.isFile())
			{
				ops.write("404,你懂的".getBytes());
				return;
			}
			BufferedInputStream bis = 
				new BufferedInputStream(new FileInputStream(file));
			BufferedOutputStream bos = 
				new BufferedOutputStream(ops);//写入流
			int l;
			while((l=bis.read())!=-1)
			{
				bos.write(l);
			}
			 bos.flush();
			 bis.close();
			 bos.close();
			
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally
		{
			try
			{
				if(socket!=null)
					socket.close();
			}catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		
	}

}

网页爬虫功能的实现:
package com.javami.kudyDemo.MyMap;

/*
 * 网页爬虫
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo2
{
	public static void main(String[]args) throws IOException
	{
		URL url = new URL("http://127.0.0.1:8888/mail.html");
		//获取到一个对象
		HttpURLConnection use = (HttpURLConnection)url.openConnection();
		//把读取到的数字转换成字符流
		BufferedReader br = 
				new BufferedReader(new InputStreamReader(use.getInputStream()));
		String line = null;
		String regex = "\\w+@+\\w+(\\.\\w+)+";//代表组里面的内容有多个
		Pattern p = Pattern.compile(regex);//将正则表达式封装成对象
		
		
		//创建正则表达式对象.与之关良..
		//循环读取一行内容.用正则表达式去比较..在取里面的符合条件的内容..再循环
		while((line=br.readLine())!=null)
		{
			//读取数据
			Matcher matcher = p.matcher(line);//用做匹配器做为比较
			//好像一个迭代器
			while(matcher.find())
			{
				String str = matcher.group();//获取到匹配到的内容
				System.out.println(str);
			}
		}
	}
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值