JAVA学习第六十五课 — 正则表达式

来源:互联网 发布:李炎恢javascript网盘 编辑:程序博客网 时间:2024/05/24 05:44

正则表达式:主要应用于操作字符串,通过一些特定的符号来体现

举例:

QQ号的校验

6~9位,0不得开头,必须是数字

String类中有matches方法

matches(String regex)
告知此字符串是否匹配给定的正则表达式。

regex,就是给定的正则表达式

public static void checkQQ() {//第一位是数字1-9,第二位以后是0-9,除去第一位数剩下数字位数范围是5到8位String regex = "[1-9][0-9]{5,8}";//正则表达式String qq = "123459";boolean flag = qq.matches(regex);System.out.println(qq+" : "+flag);}

PS:正则表达式虽然简化了书写,但是代码的阅读性极差

符号意义

正则表达式难就难在符号太多。

预定义字符类.任何字符(与行结束符可能匹配也可能不匹配)\d数字:[0-9]\D非数字: [^0-9]\s空白字符:[ \t\n\x0B\f\r]\S非空白字符:[^\s]\w单词字符:[a-zA-Z_0-9]\W非单词字符:[^\w]字符类[abc]abc(简单类)[^abc]任何字符,除了 abc(否定)[a-zA-Z]azAZ,两头的字母包括在内(范围)[a-d[m-p]]admp[a-dm-p](并集)[a-z&&[def]]def(交集)[a-z&&[^bc]]az,除了 bc[ad-z](减去)[a-z&&[^m-p]]az,而非 mp[a-lq-z](减去)

边界匹配器^行的开头$行的结尾\b单词边界\B非单词边界\A输入的开头\G上一个匹配的结尾\Z输入的结尾,仅用于最后的结束符(如果有的话)\z输入的结尾
Greedy 数量词X?X,一次或一次也没有X*X,零次或多次X+X,一次或多次X{n}X,恰好 nX{n,}X,至少 nX{n,m}X,至少 n 次,但是不超过m
Logical 运算符XYX 后跟 YX|YXY(X)X,作为捕获组
Back 引用\n任何匹配的 nth捕获组

public static void check() {<span style="white-space:pre"></span>     String string = "aoooooz";     String regex = "ao{4,}z";//正则表达式     boolean flag = string.matches(regex);     System.out.println(string+" : "+flag);}

常见功能

1.匹配 2.切割 3.替换 4.获取

匹配:用的是String类中的matches方法

public static void check() {//匹配手机号码是否正确String tel = "18753377511";//第一位是1,第二位是3或5或8//String regex = "1[358][0-9]{9}";String regex = "1[358]\\d{9}";//字符串中\,代表转义,所以再加上一个"\"将"\"转义boolean flag = tel.matches(regex);System.out.println(tel+" : "+flag);}


切割:就是以前用的String类中的split(String regex)方法,以前用的是" ",空格一般的非特殊符号,都可看作规则

空格

public static void check() {//以空格为分割,切割,空格可能出现多次String str = "a   b  c     d e f";String regex = " +";//空格出现1次或者多次String[] line = str.split(regex);for(String i : line){System.out.println(i);}}
点,PS:点本身在正则表达式中是特殊符合
String str = "a.b.c.d.e..f";String regex = "\\.+";//\.转义后还是.,所以再加一个\String[] line = str.split(regex);

以叠词为分割

正则用()来封装成组

所以叠词就可以表示为,.代表任意字符,(.)封装成组,(.)\\1,代表余下都和第一组相同

String str = "a@@@b####c...dtttef";String regex = "(.)\\1+";//String[] line = str.split(regex);

组:((A)(B(C))),共有几组,哪几组

以左括号数,

((A)(B(C))) 1

(A)    2

(B(C))     3

(C)         4

无括号就是第0组


替换:

replaceAll(String regex,String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

replaceFirst(String regex,String replacement)
使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。

public static void check() {//把叠词变为一个字符String str = "abgggggcffffdggggs";String regex = "(.)\\1+";//str = str.replaceAll(regex, "$1");System.out.println(str);}

PS:美元符号在其他参数中,可以对前一个参数中的已有的正则规则的获取

public static void check() {//18753377511 -> 187****7511String str = "18753377511";String regex = "(\\d{3})\\d{4}(\\d{4})";System.out.println(str);str = str.replaceAll(regex, "$1****$2");System.out.println(str);}

获取

正则本身就是一个对象

Pattern类

指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

//将正则的规则进行对象的封装
//Pattern p = Pattern.compile("a*b");
//通过正则对象的matcher方法字符串相关联,获取对字符串操作的匹配器对象Matcer
//Matcher m = p.matcher("aaaab");
//通过Matcher匹配器对象的方法对字符串进行操作
//boolean b = m.matches();

Matcher类

  • matches 方法尝试将整个输入序列与该模式匹配。

  • lookingAt 尝试将输入序列从头开始与该模式匹配。

  • find 方法扫描输入序列以查找与该模式匹配的下一个子序列。

public static void check() {String str = "ni hao,wohao,ta ye hao";String regex = "\\b[a-z]{3}\\b";//\\b :单词边界Pattern p = Pattern.compile(regex);Matcher m = p.matcher(str);while(m.find())//想要获取,就要先找,有没有,有才能获取{System.out.println(m.group());System.out.println(m.start()+" : "+m.end());//获取起始下标}}

练习:

将aaa...aa..aaa...bbb...b...bbb...ccc...ccc 变为 abcd

public static void test() {String str = "aaa...aa..aaa...bbb...b...bbb...ccc...ccc";System.out.println(str);String regex = "\\.+";str = str.replaceAll(regex, "");//去点regex = "(.)\\1+";str = str.replaceAll(regex, "$1");//去叠词System.out.println(str);}
排序IP地址

public static void test() {//String str = "192.0.0.1    127.0.0.24  3.3.3.5    150.15.3.41";//System.out.println("ip : "+str);//String regex = " +";//String[] strs = str.split(regex);////TreeSet<String> ts = new TreeSet<String>();//自动排序//for(String s : strs){//ts.add(s);//}//for(String s : ts){//这样排,是按照字符串排序//System.out.println(s);//}//所以在每个ip的每段数字,就用两个0补全String str = "192.0.0.1    127.0.0.24  3.3.3.5    150.15.3.41";String regex = "(\\d+)";str = str.replaceAll(regex, "00$1");System.out.println("补0 : "+str);regex = "0*(\\d{3})";str = str.replaceAll(regex, "$1");System.out.println("保留3位 : "+str);regex = " +";String[] strs = str.split(regex);TreeSet<String> ts = new TreeSet<String>();//自动排序for(String s : strs){ts.add(s);}for(String s : ts){System.out.println(s.replaceAll("0*(\\d+)", "$1"));}}

邮箱地址的简单校验

public static void test() {String mail = "aa_a@163.com.cn";String regex = "\\w+@\\w+(\\.[a-zA-Z]{2,3})+";//+代表一次或多次boolean flag = mail.matches(regex);System.out.println(mail+" : "+flag);}

注意:开发时,正则阅读性差,会不断验证,然后封装起来


练习:网页爬虫:一个程序用于在互联网中获取符合指定规则的数据

爬取邮箱地址。

public class asd {public static void main(String[] args) throws Exception {//List<String> list = getmail();//本地List<String> list =  getweb();//网络for(String i : list){System.out.println(i);}}public static List<String> getweb() throws Exception{//URL url = new URL("http://192.168.0.1:8080/myweb/mymail.html");URL url = new URL("http://news.baidu.com/");BufferedReader brin = new BufferedReader(new InputStreamReader(url.openStream()));String mail_regex = "\\w+@\\w+(\\.\\w+)+";Pattern p = Pattern.compile(mail_regex);List<String> list = new ArrayList<String>();String line = null;while((line = brin.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){list.add(m.group());}}return list;}public static List<String> getmail() throws Exception {//1.读取源文件BufferedReader br = new BufferedReader(new FileReader("g:\\mymail.html"));String mail_regex = "\\w+@\\w+(\\.\\w)+";Pattern p = Pattern.compile(mail_regex);List<String> list = new ArrayList<String>();String line = null;//2.对读取的数据进行规则的匹配,从中获取符合规则的数据while((line = br.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){//3.将符合规则的数据存储到集合list.add(m.group());}}return list;}}




0 0
原创粉丝点击