首页 > Java > 正则表达式入门

正则表达式入门

今天讲讲正则表达式,正则表达式在编程中是非常常用的一项技术,也是非常行之有效的技术,有了他,很多复杂的问题就变得的非常简单了,常见的用途有:字符串匹配(或者叫字符匹配)、字符串查找、字符串替换,典型应用有:用户注册时用户名和密码的验证、检测IP地址是否正确,从网页中揪出链接等等,从常见用途中我们看到,一言以蔽之,正则表达式就是对字符串的处理,所以正则表达式牵涉到的类有三个:java.lang.String、java.util.regex.Pattern、java.util.regex.Matcher,其实正则的用途和功能非常强大,今天老夫就写一些最基本的用法,其实那些高级用法也是从这些基本用法来的,今后看看有没有机会写一下高级用法(主要是老夫现在也不会,,,),下面我们来看看这些最基本的语法:

1. 字符类


[abc] 					a、b 或 c(简单类)
[^abc] 					任何字符,除了 a、b 或 c(否定)
[a-zA-Z] 				a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] 				a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] 			d、e 或 f(交集)
[a-z&&[^bc]] 			a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] 			a 到 z,而非 m 到 p:[a-lq-z](减去)

2. 预定义字符类


. 						任何字符(与行结束符可能匹配也可能不匹配)
d 						数字:[0-9]
D 						非数字: [^0-9]
s 						空白字符:[ tnx0Bfr]
S 						非空白字符:[^s]
w 						单词字符:[a-zA-Z_0-9]
W 						非单词字符:[^w]

3. 边界匹配器


^ 						行的开头
$ 						行的结尾
b 						单词边界
B 						非单词边界
A 						输入的开头
G 						上一个匹配的结尾
Z 						输入的结尾,仅用于最后的结束符(如果有的话)
z 						输入的结尾

4. Greedy 数量词


X? 						X,一次或一次也没有
X* 						X,零次或多次
X+ 						X,一次或多次
X{n} 					X,恰好 n 次
X{n,} 					X,至少 n 次
X{n,m} 					X,至少 n 次,但是不超过 m 次

5. 反斜线、转义和引用


反斜线字符 ('') 用于引用转义构造,如上表所定义的,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式 \ 与单个反斜线匹配,而 { 与左括号匹配。

在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分。

根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "b" 与单个退格字符匹配,而 "\b" 与单词边界匹配。字符串字面值 "(hello)" 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\(hello\)"。

其实正则表达式的用法说说难不难,但说简单一点也不简单,下面是一个例子对以上的这些语法进行测试,当我们想不起来的时候,可以把这些例子拷出来跑一下,看一下效果就知道了


package cn.bridgeli.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {
        // 简单认识正则表达式的概念

        p("abc".matches("..."));
        p("a8729a".replaceAll("\d", "-"));
        Pattern p = Pattern.compile("[a-z]{3}");
        Matcher m = p.matcher("fgh");
        p(m.matches());
        p("fgha".matches("[a-z]{3}"));

        // 初步认识. * + ?

        p("a".matches("."));
        p("aa".matches("aa"));
        p("aaaa".matches("a*"));
        p("aaaa".matches("a+"));
        p("".matches("a*"));
        p("aaaa".matches("a?"));
        p("".matches("a?"));
        p("a".matches("a?"));
        p("214523145234532".matches("\d{3,100}"));
        p("192.168.0.aaa".matches("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"));
        p("192".matches("[0-2][0-9][0-9]"));

        // 范围

        p("a".matches("[abc]"));
        p("a".matches("[^abc]"));
        p("A".matches("[a-zA-Z]"));
        p("A".matches("[a-z]|[A-Z]"));
        p("A".matches("[a-z[A-Z]]"));
        p("R".matches("[A-Z&&[RFG]]"));

        // 认识s w d 

        p(" nrt".matches("\s{4}"));
        p(" ".matches("\S"));
        p("a_8".matches("\w{3}"));
        p("abc888&^%".matches("[a-z]{1,3}\d+[&^#%]+"));
        p("\".matches("\\"));

        // POSIX Style
        p("a".matches("\p{Lower}"));

        // boundary

        p("hello sir".matches("^h.*"));
        p("hello sir".matches(".*ir$"));
        p("hello sir".matches("^h[a-z]{1,3}o\b.*"));
        p("hellosir".matches("^h[a-z]{1,3}o\b.*")); // whilte lines
        p(" n".matches("^[\s&&[^\n]]*\n$"));

        p("aaa 8888c".matches(".*\d{4}."));
        p("aaa 8888c".matches(".*\b\d{4}."));
        p("aaa8888c".matches(".*\d{4}."));
        p("aaa8888c".matches(".*\b\d{4}."));

        // email
        p("asdfasdfsafsf@dsdfsdf.com".matches("[\w[.-]]+@[\w[.-]]+\.[\w]+"));

        // matches find lookingAt

        Pattern p = Pattern.compile("\d{3,5}");
        String s = "123-34345-234-00";
        Matcher m = p.matcher(s);
        p(m.matches());
        m.reset();
        p(m.find());
        p(m.start() + "-" + m.end());
        p(m.find());
        p(m.start() + "-" + m.end());
        p(m.find());
        p(m.start() + "-" + m.end());
        p(m.find()); // p(m.start() + "-" + m.end());
        p(m.lookingAt());
        p(m.lookingAt());
        p(m.lookingAt());
        p(m.lookingAt());

        // replacement

        Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher("java Java JAVa JaVa IloveJAVA you hateJava afasdfasdf");
        StringBuffer buf = new StringBuffer();
        int i = 0;
        while (m.find()) {
            i++;
            if (i % 2 == 0) {
                m.appendReplacement(buf, "java");
            } else {
                m.appendReplacement(buf, "JAVA");
            }
        }
        m.appendTail(buf);
        p(buf);

        // group

        Pattern p = Pattern.compile("(\d{3,5})([a-z]{2})");
        String s = "123aa-34345bb-234cc-00";
        Matcher m = p.matcher(s);
        while (m.find()) {
            p(m.group());
        }

        // qulifiers

        Pattern p = Pattern.compile(".{3,10}+[0-9]");
        String s = "aaaa5bbbb68";
        Matcher m = p.matcher(s);
        if (m.find())
            p(m.start() + "-" + m.end());
        else
            p("not match!");

        // non-capturing groups

        Pattern p = Pattern.compile(".{3}(?=a)");
        String s = "444a66b";
        Matcher m = p.matcher(s);
        while (m.find()) {
            p(m.group());
        }

        // back refenrences

        Pattern p = Pattern.compile("(\d(\d))\2");
        String s = "122";
        Matcher m = p.matcher(s);
        p(m.matches());

        // flags的简写
        Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
        p("Java".matches("(?i)(java)"));
    }

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

}

全文完,如果本文对您有所帮助,请花 1 秒钟帮忙点击一下广告,谢谢。

作 者: BridgeLi,https://www.bridgeli.cn
原文链接:http://www.bridgeli.cn/archives/158
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.

请输入正确的验证码