使用java正则表达式的正确姿势

使用java正则表达式的正确姿势

一、用途

  1. 用于字符串处理
    • 字符串匹配
    • 字符串查找
    • 字符串替换
  2. 例子
    • IP地址是否正确
    • 从网页中揪出email地址
    • 从网页中揪出链接等
  3. 使用的类
    • java.lang.String
    • java.util.regex.Pattern
    • java.util.regex.Matcher

二、. * + ? 表示什么意思?

  1. *表示是一个字符
  2. X*表示X出现0个或多个
  3. X+表示出现1个或多个
  4. X?表示X出现0个或1个
  5. X{n}表示X出现n次
  6. X{n,}X最少出现n次,最多出现次数不限制
  7. X{n,m}X出现至少n次,不超过m次
  8. {}表示对字符出现次数的限制
  9. [-]表示限制字符范围
    10.[a-z]表示字符范围只能是a-z

示例代码:

        //初步认识. * + ? {} []
        p("a".matches("."));//true
        p("aa".matches("aa"));//true
        p("aaaa".matches("a*"));//true
        p("aaaa".matches("a+"));//true
        p("".matches("a*"));//true
        p("aaaa".matches("a?"));//false
        p("".matches("a?"));//true
        p("a".matches("a?"));//true
        p("21234567898".matches("\\d{3,100}"));//true
        p("192.168.0.aaa".matches("\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)"));//false
        p("192".matches("[0-2][0-9][0-9]"));//true

private static void p(Object o){
        System.out.println(o);
    }

三、[]表示什么意思?(控制范围)

  1. []表示匹配[]内其中一个字符
  2. ^表示取反
  3. -表示范围
  4. |表示或者 &&表示并且
    示例代码:
 public static void main(String[] args) {
        //范围
        p("a".matches("[abc]"));//匹配abc其中的一个字符 true
        p("a".matches("^abc"));//匹配abc之外的字符 false

        //匹配a-z或者A-Z之间的字符 3种写法
        p("A".matches("[a-zA-Z]"));//true
        p("A".matches("[a-z]|[A-Z]"));//true
        p("A".matches("[a-z[A-Z]]"));//true

        p("R".matches("[A-Z&&[RFG]]"));//A-Z之间并且是RFG三者之一 true

    }

    private static void p(Object o){
        System.out.println(o);
    }

四、常用的"\字母"表示什么意思?

  1. \d表示0-9之间的数字 [0-9]
  2. \D表示除0-9之外的字符 [^0-9]
  3. \s表示一个空白字符[ \t\n\x0b\f\r] 包含空格tab键等
  4. \S表示不包含空白字符[^\s]
  5. \w表示包含构成英文单词的字符[a-zA-Z_0-9]
  6. \W表示不包含英文单词的字符[^\w]

示例:

 		 //认识\s \w \d \
        p(" \n\r\t".matches("\\s{4}"));//true
        p(" ".matches("\\S"));//false
        p("a_0".matches("\\w{3}"));//true
        p("abc888&^%".matches("[a-z]{1,3}\\d+[&^%]+"));//true
        p("\\".matches("\\\\"));// java比较反斜杠 true

private static void p(Object o){
        System.out.println(o);
    }

五、边界

^ 表示起始位置
$ 表示结束位置
\b表示一个单词的边界(边界指的是空格、换行、空白字符、tab键等)

示例:

 		//边界
        p("hello sir".matches("^h.*"));//h开头后面跟0个或者多个字符 true
        p("hello sir".matches(".*ir$"));//ir结尾前面有0个或者多个字符 true
        p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//h开头,o后面是否包含单词边界 true
        p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));//h开头,o后面是否包含单词边界 false

 private static void p(Object o){
        System.out.println(o);
    }

六、matches、find、lookingAt

matches匹配整个字符串
find找子串
lookAt从开始位置找

示例代码:

 		Pattern p = Pattern.compile("\\d{3,5}");//全部为数字,长度为3-5
        String s = "123-23234-234-00";
        Matcher m = p.matcher(s);
        p(m.matches());//false
        m.reset();//matches和find一起使用会出现问题,一般要加reset,否则输出结果会有出入

         //find 依次查找子串
        p(m.find());//true
        //输出找到子串以后的开始位置和结束位置(前提是必须能找到这子串,否则会报错)
        p(m.start() + "-" + m.end());//输出0-3
        p(m.find());//true
        p(m.start() + "-" + m.end());//输出4-9
        p(m.find());//true
        p(m.start() + "-" + m.end());//输出10-13
        p(m.find());//false

        //lookingAt从开始位置找,每次从开头开始找
        p(m.lookingAt());//true
        p(m.lookingAt());//true
        p(m.lookingAt());//true
        p(m.lookingAt());//true

    }

    private static void p(Object o){
        System.out.println(o);
    }

七、replacement字符串替换

示例代码:

        //字符串替换replacement
        Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java");
        //把字符串中所有的java(忽略大小写),全部替换成大写的JAVA
        p(matcher.replaceAll("JAVA"));
        
        private static void p(Object o){
        System.out.println(o);
    }

输出结果如下:
输出结果
示例代码2:

 //字符串替换replacement
        Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//忽略大小写
        Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java the end");
        //要求把找到的第一个java字符串编程大写,找到的第二个变成小写,依次类推
        StringBuffer buffer = new StringBuffer();
        int i = 0;
        while (matcher.find()){
            i++;
            if(i % 2 == 0){
                matcher.appendReplacement(buffer,"java");
            }else {
                matcher.appendReplacement(buffer,"JAVA");
            }
        }
        matcher.appendTail(buffer);//加上尾巴
        p(buffer);
    }

    private static void p(Object o){
        System.out.println(o);
    }

输出结果:
输出结果

八、group分组

如何判断是第几组,数小括号就行
作用:抓取字符串中的部分内容

示例代码:

 		//分组
        Pattern pattern = Pattern.compile("(\\d{3,5})([a-z]{2})");//匹配3-5位的数字,两个字母
        String s = "123aa-345345bb-234cc-00";
        Matcher matcher = pattern.matcher(s);
        while (matcher.find()){
            //只输出3-5位的数字也就是第一组
            p(matcher.group(1));
            //只输出两位字母也就是第二组
           // p(matcher.group(2));
           
           private static void p(Object o){
        	System.out.println(o);
    		}

输出结果:
输出结果
如果group传入的是2,则输出如下:
输出结果
如果group什么都不传,则输出结果如下:
输出结果

九、读取本地网页中的email地址

示例代码:

public class EmailSpider {
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new FileReader("E:\\留下你的电子邮箱地址,我们来写Email吧。.html"));
            String line = "";
            while ((line = br.readLine()) != null){
                //判断有没有读到结尾
                parse(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void parse(String line) {
        Pattern pattern = Pattern.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()){
            System.out.println(matcher.group());
        }
    }

}

十、其他知识

向前引用:

示例代码:

//向前引用
        Pattern pattern = Pattern.compile("(\\d\\d)\\1");
        // \\1指的是后面找到的结果必须和第一个组捕捉的字符串一样
        String s = "1214";//false
//        String s = "1212";//true
        Matcher matcher = pattern.matcher(s);
        System.out.println(matcher.matches());

忽略大小写或者其他规则可以用下面这种写法:

		//忽略大小写
		//第一种写法
        Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
        //第二种写法
        p("java".matches("(?i)(java)"));

十一、有待补充 qulifiers (greedy reluctant possessive的区别)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章