黑马程序员_Java基础_正则表达式,校验QQ号,手机号,邮箱,IP地址排序,网络爬虫
来源:互联网 发布:mysql primarykey 编辑:程序博客网 时间:2024/05/02 23:19
概述:符合一定规则的表达式。用于专门用于操作字符串的。虽然字符串中有很多字符串的操作方法,但是使用起来比较繁琐,而且代码量比较多。
特点:用一些特定的符号表示以一些代码操作,简化书写,学习正则表达式就是学习一些特殊符号的使用。
好处:可以简化对字符串的复杂操作。
拿一个简单的例子比较说明:比如需要编写一个程序验证QQ号是否正确,首先QQ号必须是5到15位的,第一位1到9开头,后面可以使任意的数字。
使用传统操作字符串的方法:判断字符串长度是不是5到15,不满足则提示错误,满足在判断第一位是不是1到9,不满足提示错误,满足在循环遍历第二位以后字符是不是0到9的数字,不是则推出提示错误,满足则打印该QQ号。
class QQCheckDemo{ public static void main(String[] args) { String QQ = "75332414"; if(QQ.length()>=5 && QQ.length()<=15) { if (!(QQ.startsWith("0"))) { char[] arr = QQ.toCharArray(); boolean flag = true; for (int i=0;i<QQ.length() ;i++ ) { //System.out.println(arr[i]); if(!(arr[i]>='0' && arr[i]<='9')) { flag = false; System.out.println("出现非法字符"); break; } } if (flag) { System.out.println(QQ); } } else System.out.println("首位不能为0"); } else System.out.println("QQ位数出错"); }}
分析发现以上代码还可以简化,当字符串长度满足后,可以通过将字符串转换成长整型的数,就可以省去判断第一位和遍历判断第二位以后是不是数字的情况了。
代码:
try
{
Long l = Long.parseLong(QQ);
System.out.println("QQ:" + l);
}
catch (Exception e)
{
System.out.println("出现非法字符");
}
二,但是尽管这样做还是很麻烦,正则表达式则提供了更简便的判断字符串是否符合我们的要求。下面使用正则表达式判断QQ号是否符合要求。
Class QQCheck { public static void main(String[] args) { String qq = "534312354"; String regex = "[1-9][0-9]{4,14}"; //regex就是正则表达式的意思,在定义一个规则,第一位是1-9之间的数,从第二位开始是0-9之间的数,一共4到14个,少于4个和多于14都不行 boolean flag = qq.matches(regex); if (flag) { System.out.println("QQ号是:"qq); } else System.out.println("qq错误,请检查"); } }
1,匹配:
匹配就是判断某个字符串是否符合规定的要求,比如上面判断QQ号是不是符合要求,就属于匹配。匹配返回的结果是true或者false。
使用的方法:String类的 public boolean matches(String regex)
regex就是正则表达式,判断给定字符串是否符合该表达式。
需求:判断用户输入的手机号是不是符合要求。手机号格式13*********,15*********,18********
分析:手机号第一位是1开头,第二位只能是3或5或8,后面全部是数字,手机号是11为数的。
String tel = “13854745658”;
String regex = “1[358]\\d{9}”; //其中\d代表的是0到9的数字,也可以写成[0-9],因为windows下的反斜杠会被转义,所以在加一个反斜杠。
boolean b = tel.matches(regex);
匹配过程:返回的结果是true,过程是:先判断tel的第一个字符是1,判断第二个是不是3或5或8,是3,正确,所以判断第三位,是数字,在判断第四个是数字,在判断第五个是数字......如果任意一个不满足,则不再判断下一位,返回错误。
2,切割:
使用指定的正则表达式拆分给定的字符串,使用的方法是String类的split()方法
public String[] split(String regex)
注意:字符串拆分后返回的是一个字符串数组。
public class Demo{ public static void main(String[] args) { String str = "dsfghdfjk*dshgkj*hbj*"; String[] ss = str.split("\\*"); //需要使用两次转义字符 for(String s : ss) { System.out.println(s); } }}
举例:
(1)字符串:s = “D:\\abc\\def\\t.txt”,切割得到文件夹及目录。
String[] strs = s.split(“\\\\”);使用两个反斜杠作为转义字符。
(2)字符串:s = “sgjh sajgdskjg sdaghu e”;
需要按照多个空格进行对字符串的拆分,正则表达式为:String regex = “ +”
一个空格加上一个”+”号表示,一个或多个空格。
(3)字符串:s = “fgsdkkksdgdfiiigsdfhhsagdfkhghll”,按照叠词进行对字符串的切割。
多个空格需要用到组的概念,正则表达式:String regex= “(.)\\1+”
()就是组,可以让规则的结果被重用,点代表的是任意字符,组的出现都有编号,标号是从1开始的,使用已有的组可以通过 \n(n是组号)获取。
该表达式的获取过程是:判断第一个字符是不是字符,是,判断第二个是不是字符,是,判断是不是和第一个相等,是在判断第三个是不是和第二个相等,不是则从这个位置分割一次,在判断第四个......
3,替换:
替换是通过String类的replaceAll()方法。
public String replaceAll(String regex,String s)
将字符串的所有匹配regex的字符串替换成s。
需求:将字符串的超过3位的数字全部替换成#号。
public class Demo2{ public static void main(String[] args) { String str = "agsdf1535dsh453432653dfshg3546";//正则表达式:\d代表0到9之间的数字,{3,}代表数字出现三次或三次以上 String regex = "\\d{3,}""; str = str.replaceAll(regex,"#"); System.out.println(str); }}
举例:
给定的字符串中有叠词,现在要将重叠的字符替换成一个该字符。
String s = “asdgdddsdggsagggrrryrtusdfgfd”;
String regex = “(.)\\1+”;
s = s.replaceAll(regex,”$1”);
$是一个特殊符号,如果想将多个连续相同字符替换成指定该连续字符就要使用$符号。
4,获取。
四,正则表达式的获取
获取比较特殊,和匹配,切割,替换都不同。获取是将字符串中的复合规则的子串抽取出来。
步骤:
1,将正则表达式封装成对象。
2,让正则表达式和要操作的字符串关联。
3,关联后获取正则表达式的匹配引擎。
4,通过引擎对复合规则的子串进行操作,比如取出。
方法是首先获得Pattern类的对象,因为正则表达式必须首先被编译成此类的实例,然后通过Matcher类的matcher方法创建匹配器,Matcher对象可以与任意的字符串串序列匹配。
Pattern类没有构造函数,所以要通过静态方法获取该类对象。调用顺序是:
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
其实String类的matchs方法,底层使用的就是Pattern类和Matcher类对象来完成的,只不过是String类对其进行了封装,使用起来比较方便,但是有局限性。
需求:需求:获取句子中的三个字母的单词,打印出结果。给定句子:nothing is impossible,never give up our dream.
import java.util.regex.*;public class Test1{ public static void main(String[] args) { String str = " nothing is impossible,never give up our dream abc."; String reg = "\\b[a-z]{3}\\b"; //将正则表达式封装成对象 Pattern p = Pattern.compile(reg); //将正则表达式与要操作的字符串关联,获取匹配器 Matcher m = p.matcher(str); //将规则作用在字符串 //boolean b = m.find();//这里find是查找三位字母的单词,直到找到第一个为止 //System.out.println(m.group());//获取匹配后的结果 //要想全部找到必须使用循环,可以将find方法看做是一个迭代器。 while(m.find()) { System.out.println(m.group()); } }}
正则表达式:String reg = "\\b[a-z]{3}\\b";的含义是:a到z的字母出现三次,\b表示的是单词的边界,两边是边界。
五,正则表达式的几个练习
正则表达式在的解题思路是:
(1)如果只想知道该字符串是对或错,使用匹配。matches()
(2)如果要将字符串按照给定的规则进行拆分成多个子串,使用切割。split()
(3)如果要将已有的字符串变成另一个,则使用替换。replaceAll()
(4)要拿到符合要求的子串,使用获取。
1,练习一:校验邮箱是否正确。
分析:邮箱格式必须要有@符号,@左边是字母数字的组合,位数字5到20位之间,@右边挨着@的部分是字母或数字的组合(可以使纯数字或字母),它后面是.com,.cn,.edu之类的字符,所以可以将带点的那一部分封装成组,出现一次或多次。
public class Test1{ public static void main(String[] args) { String mail = "s334g@qq.com.cn"; mail = "13456@1.n"; //必须有@符号,它左边是数字或字母或数字字母组合,出现5到20次。 //它右边是字母数字或组合,出现一次或多次,它后面是.com之类的。出现一次或多次 String reg = "[a-zA-Z_0-9]{5,20}@[a-zA-Z_0-9]+(\\.[a-zA-Z]+)+"; //不精确的匹配,建议使用上面的正则表达式,比较精确 //reg = "\\w{5,20}@\\w+(\\.\\w+)+";//不同在于最后的部分,可以使数字或字母 if(mail.matches(reg)) System.out.println("邮箱是:" + mail); else System.out.println("邮箱格式错误!"); }}
2,练习二:将给定的字符串变成一句正常的话。例如:我我我我我我=====要要要。。。。。进进进..........黑黑黑马马------学学,,,,,,,习习习。。。变成:我要进黑马学习
代码:
class Test2{ public static void main(String[] args) { String s = "我我我我我我=====要要要。。。。。进进进..........黑黑黑马马------学学,,,,,,,习习习。。。"; //首先要将中间的符号全部去掉 s = s.replaceAll("\\=",""); s = s.replaceAll("\\。",""); s = s.replaceAll("\\.",""); s = s.replaceAll("\\-",""); s = s.replaceAll("\\,",""); System.out.println(s); //去掉重复文字 s = s.replaceAll("(.)\\1+","$1");//将出现的任意字符当做第一个组1是组的编号 System.out.println(s); }}
3,练习三:将IP地址按照地址段顺序进行排序,给定的地址段格式是:
192.168.0.2 185.64.51 192.120.75 27.152.52 64.28.125.0 192.168.5.4
分析:1,将每一个ip地址的每一段变成三位,因为最高是三位,如果不这样的话,自然排序会按照第一个数字排序,2.152.5.3就会排到192.168.1.0之后。正确方法应该用002.152.005.003与192.168.001.000比较才对。
思路:1,将每位ip的每段前面加两个0,
2,然后去掉每个ip每段后三位的前面一部分,也就是保证每段是三位数。
3,将字符串按照空格拆分,得到每个ip,添加到TreeSet集合,因为TreeSet集合有排序功能。
import java.util.*;class Test3{ public static void main(String[] args) { String ip = "192.168.0.2 185.64.51 192.120.75 27.152.52 64.28.125.0 192.168.5.4"; String reg = "(\\d+)";//找到连续的数字,该规则要重用,所以封装成组 //将每段前面加上2个0 ip = ip.replaceAll(reg,"00$1");//在第一组前面加两个0 //System.out.println(ip); //值保留每段的后三位 reg = "0*(\\d{3})";//开头是0出现零次或多次,然后是数字出现三次,将数字出现三次封装成组,重用 ip = ip.replaceAll(reg,"$1");//替换成组1,也就是数字出现三次 //System.out.println(ip); //拆分ip,获得每个ip String[] str = ip.split(" +"); //将每个ip存储到集合中 TreeSet<String> trees = new TreeSet<>(); for(String s : str) { trees.add(s); } //迭代集合,就是按照大小排序后的结果 for(String st : trees) { st = st.replaceAll("0*(\\d+)","$1");//第一位是0出现零次或多次,然后是数字,出现最少一次,将数字出现一次或多次封装成组 System.out.println(st); } }}
六,综合应用。
需求:编写一个网络爬虫,从一个文本文件中读取所有的邮箱。
分析:使用流从一个文本文件中读取每行文本数据,然后获取Pattern对象,每读取一行字符串就获取一次匹配器,寻找该行字符串是不是有符合正则表达式的部分。知道每行字符串都匹配完结束循环。
import java.io.*;import java.util.*;import java.util.regex.*;class Test4{public static void main(String[] args) throws Exception {Scanner in = new Scanner(new FileInputStream("mail.txt"));//邮箱的正则表达式String reg = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]+(\\.[a-zA-Z]+)+";Pattern p = Pattern.compile(reg);//循环匹配每行字符串while(in.hasNextLine()) {String line = in.nextLine();//System.out.println(line);Matcher m = p.matcher(line);while(m.find()) {System.out.println(m.group());}}in.close();}}
如何获取一个网页上的所有邮箱地址呢?只需要将输入流换成网络上的流就可以了。使用URL类获取。
URL url = new URL(“http://127.0.0.1:8080/web/mail.html”);//获取本地主机的Tomcat服务器上的网页。
URLConnection con = url.openConnection();
Scanner in = new Scanner(con.getInputStream());
- 黑马程序员_Java基础_正则表达式,校验QQ号,手机号,邮箱,IP地址排序,网络爬虫
- 黑马程序员_Java基础_正则表达式
- 黑马程序员_Java基础_正则表达式
- 黑马程序员_java基础_正则表达式
- 邮箱、手机号、QQ号正则表达式
- 黑马程序员_Java基础_正则表达式_25
- 黑马程序员_java入门_正则表达式
- Java正则表达式校验邮箱和手机号
- Java正则表达式校验邮箱和手机号
- Java正则表达式校验邮箱和手机号
- Java正则表达式校验邮箱和手机号
- Java正则表达式校验邮箱和手机号
- Java正则表达式校验邮箱和手机号
- android 正则表达式校验邮箱、手机号等
- java正则表达式校验手机号、邮箱、身份证
- 黑马程序员_java基础-正则表达式
- 黑马程序员_Java基础_网络编程
- 黑马程序员_JAVA基础_网络(一)
- 2014年5月份计划
- 使用工具安全删除Windows 7系统及数据资料方法介绍
- Elipse下配置Ruby、Python、PHP环境
- Java 通过反射机制动态调用java类方法
- 精挑细选
- 黑马程序员_Java基础_正则表达式,校验QQ号,手机号,邮箱,IP地址排序,网络爬虫
- JAVA 阻塞IO流
- random.sample
- 自己操作过程的Git
- 让Eclipse不再以蜗牛般速度运行的解决技巧
- 为编写的Windows程序提升权限
- treeview节点拖动
- 下一代游戏主机,8GB内存怎么够
- 【机器学习算法-python实现】KNN-k近邻算法的实现(附源码)