黑马程序员——正则表达式(1)

------- android培训java培训、期待与您交流! ----------
/**使用正则表达式的基本方法:
(一)建立
String regex="";//regex匹配
String input="";//input输入

Pattern p= Pattern.compile(regex);//将给定的正则表达式(regex)编译compile()到模式(Pattern)中。 static Pattern	compile(String regex)      
Matcher m=p.matcher(input);//创建匹配(match)给定输入(input)与此模式的匹配器(Matcher)。 Matcher	matcher(CharSequence input)

(二)处理匹配结果
//如果是用regex匹配全部input则使用。尝试将整个区域与模式匹配:boolean	matches()   
m.matches()
//通常只需要匹配部分input,则使用m.find() 尝试查找与该模式匹配的输入序列的下一个子序列:boolean	find([int start]) 
//抛出:IndexOutOfBoundsException - 如果开始点小于零或大于输入序列的长度。
  int tmpStart=0
  while(m.find())
  {
  	//...
  	tmpStart=m.end();//end()返回的是当前与模式匹配的子序列的结尾的位置。
  }
 
 (三)关于捕获
 regex中()表示需要捕获的群组,匹配后,得到一个数组存放所有的捕获。
 返回此匹配器模式中的捕获组数:int	groupCount()//捕获是从1开始计算,0始终表示整个regex,所以想返回整个匹配的子序列可以用m.group()。
 返回由以前匹配操作所匹配的输入子序列: String	group()           
 
 for(int i=0;i<=m.groupCount();++i)//i=0表示m.group(0)即整个regex的匹配
 {
 	System.out.print(m.group(i));
 	System.out.print(" ,starts at pos:"+m.start(i));
 	System.out.print(" ,ends at pos:"+m.end(i));
 	System.out.println();
 }
      
(四)替换
1.替换模式与给定替换字符串相匹配的输入序列的每个子序列。String	replaceAll(String replacement) 
    m.replaceAll("#");//input的所有与regex匹配的子序列都被替换成"#";
2.替换模式与给定替换字符串匹配的输入序列的第一个子序列。String	replaceFirst(String replacement) 
    m.replaceFirst("#");//input第一个与regex匹配的子序列被替换成"#";
3.用捕获的内容进行替换
	m.replaceFirst("$1");//用第一个捕获的内容替换整个与regex匹配的子序列。	
	
	String forMatch="15851844444aasdddd15851866666ddd15851822222ddd15851899999";//ddd15851877777
	String regex="1[3458]\\d{4}(\\d)\\1{4}";
	Pattern p=Pattern.compile(regex);		
	Matcher m=p.matcher(forMatch);
	
	int tmpStart=0;
	int cntMatches=0;
	while(m.find(tmpStart))
	{			
		tmpStart=m.end();
		System.out.println("matches "+(++cntMatches)+" : ");
		for(int i=0;i<=m.groupCount();++i)
		{
			System.out.print("match "+i+" : ");
			System.out.print(m.group(i));
		 	System.out.print(" ,starts at pos:"+m.start(i));
		 	System.out.print(" ,ends at pos:"+m.end(i));
		 	System.out.println();
		}
		System.out.println();
	}
*/
/**
练习题: 写一个正则表达式,可以匹配尾号5连的手机号。规则: 第1位是1,第二位可以是数字3458其中之一,后面4位任意数字,最后5位为任意相同的数字。
例如:18601088888、13912366666

@author rexih
0.首先根据题目要求制作一个随机文本文件,文件内有字母和手机号码
a.创建一个手机号码生成器
规则: 第1位是1,第二位可以是数字3458其中之一,后面9位任意数字。
b.将号码随机插入到随机字母文本中。

1.建立一个ArrayList<String>存储捕获到的手机号码,建立一个字符缓冲区sb存放将作为输入的字符序列;
2.读取文件的内容 src:文件 FileInputStream //dest:屏幕
3.通过read(buf)方法读取输入流的字节数据,并将读取到的字节数据附加到字符缓冲区末尾
4.将sb转换成输入input
5.编写regex
6.将regex编译进模式Pattern
7.获取匹配器Matcher m
8.通过m的find()方法寻找每一个匹配,并通过group()获取符合要求的电话号码
9.将电话号码的字符串存入ArrayList<String>
10.打印集合中的所有电话号码。
*/
import java.io.*;
import java.util.regex.*;
import java.util.*;
public class Test
{
	public static void main(String[] args) //throws Exception
	{			
		ArrayList<String> al=new ArrayList<String>();
		InputStream in=null;		
		byte[] buf=new byte[1024];
		int cntBuf=0;
		StringBuilder sb=new StringBuilder();
		//生成一个用于演示的文本文件
		File f=buildAFile();
		try 
		{
			//读取文件的内容 src:文件 FileInputStream 
			in=new FileInputStream(f);
			//通过read(buf)方法读取输入流的字节数据
			while(-1!=(cntBuf=in.read(buf)))
			{
				//将读取到的字节数据附加到字符缓冲区末尾
				sb.append(new String(buf,0,cntBuf));
			}			
		} catch (IOException e) 
		{
			throw new RuntimeException("read file failed");
		}
		finally
		{
			//关闭输入流
			if(null!=in)
			{
				try 
				{
					in.close();
				} catch (IOException e) 
				{
					throw new RuntimeException("input close failed");
				}				
			}	
		}	
	
		//准备好正则表达式使用的输入
		String input=sb.toString();
		/*准备好正则表达式:
		按照题目要求:
		第一位为 1			1
		第二位为3458之一		[3458]
		中间4位任意			\d{4}
		后5位相同			(\d)\1{4}	//(\d)表示将这个数字捕获因为5个数字相同,所以该数字之后4个数字应该与之相同,即与\1相同,也就是\1{4}
		*/
		String regex="1[3458]\\d{4}(\\d)\\1{4}";
		//将正则表达式编译进模式
		Pattern p=Pattern.compile(regex);
		//获取输入和模式的匹配器m
		Matcher m=p.matcher(input);
		
		//获取下一次匹配的起始位置(上次匹配结果的末尾)
		int tmpStart=0;
		//因为号码不止一个所以需要多次匹配以获取所有号码
		while(m.find(tmpStart))
		{			
			tmpStart=m.end();//获取下一次匹配的起始位置(上次匹配结果的末尾)
			newPrint("get a phone number: "+m.group());//m.group()获取本次匹配的子序列。
			al.add(m.group());//添加入“电话本”
		}
		newPrint("All  the cell phone numbers stored in ArrayList:");
		int cnt=0;
		for(String s:al)
		{
			newPrint((++cnt)+":\t"+s);
		}
		newPrint("The orginal file is saved at:\n"+f.getAbsolutePath());	
	}
	//生成一个文件
	public static File buildAFile()
	{		
		//创建一个File对象用于保存文件,并且返回给主函数调用。
		File f=new File("regex.txt");
		FileOutputStream fout=null;
		try 
		{
			//dest是文件,使用FileOutputStream
			fout=new FileOutputStream(f);
			
			writeContent(fout);//向文件写入内容			
		} catch (IOException e) 
		{
			throw new RuntimeException("builing a file failed");
		}
		finally
		{
			//关闭资源
			if(null!=fout)				
			{
				try
				{
					fout.close();
				} catch (IOException e) 
				{
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}			
			}
		}
		return f;
	}	
	//向输出流写入内容
	public static void writeContent(OutputStream out)throws IOException//异常返回给invoker处理
	{
		int offset=0;
		for(int i=0;i<100;++i)
		{
			//每一百个字母中随机选择一个位置,随机判断是否用电话号码替代掉,概率为1/10
			offset=getRand(0,99);
			for(int j=0;j<offset;++j)
			{
				out.write(getRandAlphabet());
			}
			//判断该字符是否用电话号码替代掉,概率为1/10
			if(5==getRand(0,10))
			{
				out.write(phoneNumGen());
			}else
			{
				out.write(getRandAlphabet());
			}
			
			for(int j=offset+1;j<100;++j)
			{
				out.write(getRandAlphabet());
			}
		}
	}
	//使用Math类的random()方法获取[0.0,1.0)的随机数乘以length+begin再取整则可以得到[begin,begin+length)的整数
	public static int getRand(int begin,int length)
	{		
		return (int)(Math.random()*length+begin);
	}	
	//随机获取一个小写字母a的ascii为97,一共有26个字母
	public static char getRandAlphabet()
	{		
		return (char)getRand(97,26);		
	}
	//创建一个手机号码生成器。规则: 第1位是1,第二位可以是数字3458其中之一,后面9位任意数字。
	public static byte[] phoneNumGen()
	{
		//48是0的ascii码
		final int ZERO=48;
		//为了方便字节流输出数据,将返回值定义为byte[]
		byte[] phoneNum=new byte[11];
		//step1:第一位为1
		phoneNum[0]=(byte)(1+ZERO);		
		//step2:随机获取第二位的数字
		switch(getRand(1,4))
		{
		case 1:
			phoneNum[1]=(byte)(3+ZERO);
			break;
		case 2:
			phoneNum[1]=(byte)(4+ZERO);
			break;
		case 3:
			phoneNum[1]=(byte)(5+ZERO);
			break;
		case 4:
			phoneNum[1]=(byte)(8+ZERO);
			break;
		}
		//step3:随机写入中间4位
		for(int i=2;i<6;++i)
		{
			phoneNum[i]=(byte)getRand(ZERO,10);
		}		
		//step4:为了让程序结果更能说明问题,先生成一个随机数,若是0则后五位随机,若是1则后五位相同
		if(0==getRand(0,2))
		{
			for(int i=6;i<11;++i)
			{
				phoneNum[i]=(byte)getRand(ZERO,10);
			}
		}
		else
		{
			byte tmp=(byte)getRand(ZERO,10);
			for(int i=6;i<11;++i)
			{
				phoneNum[i]=tmp;
			}
		}
		return phoneNum;
	}
	//简化书写,打印简单的信息。
	public static void newPrint(Object obj)
	{		
		System.out.println(obj);
	}
	
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值