一、正则表达式——特点
正则表达式:符合一定规则的表达式。 作用:用于专门操作字符串。 String 类中对正则表达式应用的其中一个方法: boolean matches(String regex); 判断此字符串是否匹配给定的正则表达式。 需求: 对QQ号码进行校验 要求:长度为5~15位 0不能开头,只能是数字 示例代码:class RegexDemo { public static void main(String[] args) { String qq = "123456"; String regex = "[1-9][0-9]{4,14}"; boolean flag = qq.matches(regex); if(flag) System.out.println("qq: "+qq); else System.out.println(qq+"...不合法"); } }
二、正则表达式——匹配
1、正则表达式的特点:
用一些特定的符号来表示一些代码操作,这样就简化了书写。
所以学习正则表达式,就是学习一些特殊符号的使用(详见API)。
2、常用符号
3、正则表达式是专门用来操作字符串的,其具体操作功能(匹配、切割、替换、获取): 匹配: String 类中的方法: boolean matches(String regex)。用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回 false 。 示例代码:class RegecDemo { public static void main(String[] args) { demo(); checkTel(); } public static void demo() { String str = "+b"; String reg = "[^adcd][a-z]";//该字符串只有两位,第一位不是abcd,第二位是a-z之间任意一个 boolean bl = str.matches(reg); System.out.println("bl="+bl); } //手机号只有13xxx 15xxx 18xxx public static void checkTel() { String str = "18648524657"; String reg = "1[358]\\d{9}"; boolean bl = str.matches(reg); System.out.println("bl="+bl); } }
三、正则表达式——切割
1、正则表达式的好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则越长,阅读性越差。
2、在正则表达式中,为了可以让规则的结果被重用,可以将规格封装成一个组,用()完成;
组的出现都有编号,从1开始。想要在同一个正则表达式中使用已有的组,可以通过\n来获取,n代表第几组。
问题:"((())())":判断该正则表达式有几组?
看左括号,有几个左括号就有几组,第几个左括号代表第几组(详见API(组和捕获))。
3、切割方法:
String 类中另一个使用正则表达式的方法:
String[] split(String regex); 根据给定正则表达式的匹配拆分此字符串。
代码:class RegecDemo { public static void main(String[] args) { splitDemo("zhangsan.lisi.wangwu","\\."); /* 因为 . 是一个具有特殊意义的字符:代表任意字符,如果只是写 . 则会用任意子符切割; 所以需要用 \. 来转义,表示出其本来的含义; 但是,字符串中 \ 代表转义字符, \. 转义没有任何意义; 所以在字符串中,最终用 \\. 来表示一个 . */ splitDemo("c:\\abc\\a.txt","\\\\");//与上一个同理,用 \\\\ 来表示 \\ //按照叠词完成切割。 splitDemo("abc55efg111hij","(.)\\1+"); /* (.) 表示把任意字符作为一个组 \1 表示捕获第一组,但是在字符串中需要使用 \\1 来表示 + 表示该组出现一次或者多次 */ } public static void splitDemo(String str, String reg) { String[] arr = str.split(reg); for(String s : arr) { System.out.println(s); } System.out.println("-----------"); } }
四、正则表达式——替换
1、替换功能使用的是 String 类中的方法:
String replaceAll(String regex, String replacement); 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式regex的子字符串。
2、$ 符号在正则表达式中的意义:
在正则表达式中,用()来封装一个组;
如果是同一个字符串中,使用\n 来捕获组;
如果是不同字符串中,则使用 $n 来捕获组。
代码示例:class RegecDemo { public static void main(String[] args) { String str = "wer13899804546tylag13245eaga466412age"; //将字符串中的数组替换成#; replaceAllDemo(str,"\\d{5,}","#"); String st = "erkkyalllhinlazzzzo"; //将叠词替换成& replaceAllDemo(st,"(.)\\1+","&"); //将重叠的字母替换成单个字母 replaceAllDemo(st,"(.)\\1+","$1"); /* (.) 封装了一个组,在同一个字符串中使用 \\1 则可以捕获该组; 但是在第二个字符串中,需要使用 $1 来捕获前一个正则表达式的第一组。 */ } public static void replaceAllDemo(String str, String reg, String newStr) { str = str.replaceAll(reg,newStr); System.out.println(str); } }
五、正则表达式——获取
先介绍两个类:
1、 Pattern
正则表达式的编译表现形式 Pattern 类。
java.lang.Object
-java.util.regex.Pattern
public final class Pattern extends Object implements Serializable
该类没有构造函数,只能通过其静态方法获取对象:
static Pattern compile(String regex); 将给定的正则表达式编译到模式中。
2、 Matcher
java.util.regex.Matcher
public final class Matcher extends Object implements MatchResult
通过解释 Pattern 对 character sequence 执行匹配操作的引擎
获取:将字符串中符合规则的子串取出。
操作步骤:
1、将正则表达式封装成对象;
Pattern p = Pattern.compile(reg);
2、让正则对象和要操作的字符串相关联;
Matcher m = p.matcher(str);
Matcher 是一个匹配器,也称之为引擎。
3、关联后,获取正则匹配引擎;
m.find();
4、通过引擎对符合规则的子串进行操作,比如取出。
m.group();
注意:只有先去找,才能去取。也就是先find(),再group();
其实String类中的matches方法,用的就是Pattern和Mather对象,同时调用了Mather类中的metches方法来完成的;
只不过被String类的中的matches方法封装后,用起来较为简单。
代码:import java.util.regex.*; class RegexDemo3 { public static void main(String[] args) { getDemo(); } public static void getDemo() { String str = "ming tian jiu yao fang jia le ,da jia."; String reg = "\\b[a-zA-Z]{4}\\b";//注意:\\b代表单词边界 //将规则封装成对象。 Pattern p = Pattern.compile(reg); //让正则对象和要作用的字符串相关联,获取匹配器对象。 Matcher m = p.matcher(str); //boolean b = m.find();//将规则作用到字符串上,并进行符合规则的子串查找。 //System.out.println(b); //System.out.println(m.group()); System.out.println("matches: "+m.matches());//此处以找完了ming,索引位置已经改变,下一次查找时,从tian开始找。 while(m.find()) { System.out.println(m.group()); System.out.println(m.start()+"....."+m.end()); } } //String类的matches()方法的底层调用原理:代码示例 public static void demo() { String s = "132645"; String regex = "[1-9][0-9]{4,14}"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(s); boolean b = m.matches(); System.out.println("demo: b="+b); } }
六、正则表达式——练习一
使用正则表达式时的选择方法:
1、如果只想知道该字符串是对是错,使用匹配;
2、想要将已有的字符串变成另一个字符串,使用替换;
3、想要按照指定的方式将字符串变成多个字符串,使用切割(获取规则以外的子串);
4、想要拿到符合要求的字符子串,使用获取(获取符合规则的子串)。
练习一:<pre name="code" class="java"> class RegexTest { public static void main(String[] args) { test(); } public static void test() { String str = "我我...我我...我要..要要...要要....学学学....学学...编编编...编程..程.程程...程...程"; /* 将已有字符串变成另一个字符串,使用替换 1、先将.去掉; 2、再将多个重复的内容变成单个内容。 */ str = str.replaceAll("\\.+",""); str = str.replaceAll("(.)\\1+","$1"); System.out.println(str); } }
</pre>
七、正则表达式——练习二
练习二:
192.168.1.254 102.26.16.40 10.10.20.35 2.1.5.59 8.24.68.134
将IP地址进行地址段顺序的排序
思路:按字符串的自然顺序排序,只要让他们每一段都是3位即可。
1、每一段前面都补两个0;
2、将每一段只保留3位。那么,所有的IP地址都是每一段3位;
3、用空格将每一个IP地址切开;
4、将切开后得到的数字遍历,并将每一个地址放到TreeSet集合中,因为TreeSet集合可以进行自然顺序的排序;
5、遍历取出这个TreeSet集合,并去掉每一段地址前面的 0 。
代码:class RegexTest { public static void main(String[] args) { ipSort(); checkMail(); } public static void ipSort() { String ip = "192.168.1.254 102.26.16.40 10.10.20.35 2.1.5.59 8.24.68.134"; //1、没一段数字前面都补上两个 0 ip = ip.replaceAll("(\\d+)","00$1"); System.out.println(ip); //2、每一段保留三位数字,将多余的0去掉 ip = ip.replaceAll("0*(\\d{3})","$1"); System.out.println(ip); //3、用空格将每一个IP地址切开 String[] arr = ip.split(" +"); //4、将切开后得到的数字遍历,并将每一个地址放到TreeSet集合中 TreeSet<String> ts = new TreeSet<String>(); for(String s : arr) { ts.add(s); } //5、遍历这个TreeSet集合,并去掉每一段地址前面的 0 for(String s : ts) { System.out.println(s.replaceAll("0*(\\d+)","$1")); } } /* 需求:对邮件地址进行校验。 */ public static void checkMail() { String mail = "abcd12@sina.com.cn"; String regex = "[a-zA-z0-9_]{6,12}@[a-z0-9]+(\\.[a-zA-z]+){1,3}"; boolean b = mail.matches(regex); System.out.println(b); } }
八、正则表达式——网页爬虫
import java.io.*; import java.util.regex.*; import java.net.*; class RegexTest3 { public static void main(String[] args) throws Exception { getMail_1(); } public static void getMail() throws Exception { BufferedReader bufr = new BufferedReader(new FileReader("mail.txt")); String line = null; String regex = "[a-zA-Z0-9]{3,15}@[a-zA-Z0-9]+(\\.[a-zA-z]+)+"; Pattern p = Pattern.compile(regex); while((line=bufr.readLine())!=null) { Matcher m = p.matcher(line); while(m.find()) { System.out.println(m.group()); } } bufr.close(); } public static void getMail_1() throws Exception { URL url = new URL("http://10.20.10.5:8080/myweb/mail.html"); URLConnection conn = url.openConnection(); BufferedReader bufr = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; String regex = "[a-zA-Z0-9]{3,15}@[a-zA-Z0-9]+(\\.[a-zA-z]+)+"; Pattern p = Pattern.compile(regex); while((line=bufr.readLine())!=null) { Matcher m = p.matcher(line); while(m.find()) { System.out.println(m.group()); } } } }