【java学习】正则表达式(Regular Expression)

1,概念

正则表达式(Regular Expression)起源于人类神经系统的研究。正则表达式的定义有以下几种:
① 用某种模式去匹配一类字符串的公式,它主要是用来描述字符串匹配的工具。
②述了一种字符串匹配的模式。可以用来检查字符串是否含有某种子串、将匹配的子串做替换或者从中取出符合某个条件的子串等。
③由普通字符(a-z)以及特殊字符(元字符)组成的文字模式,正则表达式作为一个模版,将某个字符模式与所搜索的字符串进行匹配。
④用于描述某些规则的的工具。这些规则经常用于处理字符串中的查找或替换字符串。也就是说正则表达式就是记录文本规则的代码。
⑤用一个字符串来描述一个特征,然后去验证另一个字符串是否符合这个特征。

2,规则

1)元字符(Metacharacter)

元字符(Metacharacter)是一类非常特殊的字符,它能够匹配一个位置或字符集合中的一个字符,如:、 \w等。根据功能,元字符可以分为两种类型:匹配位置的元字符和匹配字符的元字符。

1.1 ^(脱字符号)

匹配一个位置;匹配行的开头。单个^匹配任意行。

^string  匹配以string开头的行

1.2 $(美元符号)

匹配一个位置;匹配行的结尾。单个$匹配一个空行。

string$  匹配以string结尾的行
^string$ 匹配以string开始和结尾的行

1.3 \b

匹配一个位置;匹配单词的开始和结尾,但\b不匹配空格、标点符号或换行符号。

\bstr  匹配以str开始的单词
str\b  匹配以str结尾的单词

2.1 .(点号)

匹配字符的元字符;匹配除换行之外的任意字符。

2.2 \w

匹配字符的元字符;\w匹配单词字符(包括字母、汉字、下划线和数字)。

2.3 \W

匹配字符的元字符;\W匹配任意非单词字符。

2.4 s\

匹配字符的元字符;\s匹配任意的空白字符,如空格、制表符、换行等。

2.5 \S

匹配字符的元字符;\S匹配任意的非空白字符。

2.6 \d

匹配字符的元字符;\d匹配任意数字字符。

2.7 \D

匹配字符的元字符;\D匹配任意的非数字字符。

^.$   匹配一个非空行,在该行中可以包含除了换行符以外的任意字符。
^\w$  匹配一个非空行,并且该行中只能包含字母、数字、下划线和汉字中的任意字符。
\ba\w\w\w\w\w\w\\b   匹配以字母a开头长度等于7的任意单词
\ba\w\w\w\d\d\d\D\b  匹配以字母a开头后面有3个字符三个数字和1个非数字字符长度等于8的单词

2)字符类

字符类可以在[](方括号)中定义。

[012345]    匹配数字0到5中的任意一个。
[0-5]       匹配数字0到5中的任意一个。

<H[123456]> 匹配HTML标签中的H1H6[Jj]ack     匹配字符串Jack或jack。
[a-z]       匹配任何小写字母
[A-Z]       匹配任意大写字母。
[-a]        匹配-或者a。如果要在字符类中包含连字符,则必须包含在第一位
[^abc]      匹配除了abc以外的任意字符
[^-]        匹配除了连字符以外的任意字符
a[^b]       匹配a之后不是b的字符串。

---常用字符类---
\w  匹配单词字符(包括字母、数字、下划线和汉字)
\W  匹配任意的非单词字符(包括字母、数字、下划线和汉字)
\s  匹配任意的空白字符,如空格、制表符、换行符、中文全角空格等
\S  匹配任意的非空白字符
\d  匹配任意数字
\D  匹配任意的非数字字符
\B  匹配不是单词开头或结束的位置
[abc]   匹配字符集中的任何字符
[^abc]  匹配除了字符集中包含字符的任意字符
[0-9a-z_A-Z_]   匹配任何数字、字母、下划线。等同于\w
\p{name}    匹配{name}指定的命名字符类中的任何字符
\P{name}    匹配除了{name}指定的命名字符类中之外的任何字符
.           匹配除了换行符号之外的任意字符
[^0-9a-zA-Z_]   等同于\W

4)字符转义

\r, \n      代表回车和换行符
\t          制表符
\\           "\" 
\^          匹配 ^ 符号本身
\$         匹配 $ 符号本身
\.          匹配小数点(.)本身
\\?         匹配问号

5)限定符

正则表达式的元字符一次只能匹配一个位置或一个字符,如果需要匹配零个一个或多个字符时,则需要使用限定符。

*       匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。
+       匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
?       匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do""does" 中的"do" 。? 等价于 {0,1}{n}     n是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,}    n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+''o{0,}' 则等价于 'o*'{n,m}   m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
*?      尽可能少的使用重复的第一个匹配
+?      尽可能少的使用重复但至少使用一次
??      如果有可能使用零次重复或一次重复。
{n}?    等同于{n}
{n,}?   尽可能少的使用重复但至少重复n次
{n,m}?  介于n次和m次之间,尽可能少的使用重复。

6)匹配方式

我们普通的字符类均是贪婪匹配,如果在字符类后加个问号(?)则表示懒惰匹配,要成为支配性匹配则在懒惰匹配后加个问号(?).

①惰性匹配

趋向于最小长度匹配。
先看字符串中的第一个字母是不是一个匹配,如果单独一个字符还不够就读入下一个字符,如果还没有发现匹配,就不断地从后续字符中读取,只道发现一个合适的匹配,然后开始下一次的匹配。

②贪婪匹配

趋向于最大长度匹配。
先看整个字符串是不是一个匹配,如果没有发现匹配,它去掉字符串中最后一个字符并再次尝试,如果还没有发现匹配,那么再次去掉最后一个字符,这个过程会一直重复直到发现一个匹配或字符串不剩一个字符为止。

③支配性匹配

只尝试匹配整个字符串,如果整个字符串不能产生一个匹配,则不再进行尝试。

7)断言(零宽断言,环视)

环视强调的是它所在的位置,前面或者后面,必须满足环视表达式中的匹配情况,才能匹配成功。
环视可以认为是虚拟加入到它所在位置的附加判断条件,并不消耗正则的匹配字符。

①类型

(一)肯定和否定
1、肯定:(?=exp) 和 (?<=exp)
2、否定:(?!exp) 和 (?

②举例

/a(?=\d)  //匹配a1,a2 不匹配ab,a

3,字符串处理

1)匹配-matches方法

    // 校验一串数字,要求第一位不能是0,长度为5-15位
    private static void match(String str) {
        String regex = "[1-9]\\d{4,14}";
        boolean flag = str.matches(regex);
        if (flag) {
            System.out.println("...is ok");
        } else {
            System.out.println("...不合法");
        }
    }

2)切割-split()方法

    private static void split_str(String str){      
        String reg = " +";//按照多个空格来进行切割
        String[] arr = str.split(reg);          
        for(String s : arr){
            System.out.println(s);
        }
    }

3)替换-replaceAll(regex,str)方法。

//替换:将重叠的字符替换成单个字母。zzzz->z
public static void replaceAll_str(String str){  
    /*
     * //.匹配任意一个字符,不包括换行
     * (.)小括号表示捕获这个匹配到的字符
     * \\1表示捕获的组号,也就是()内的字符
     * 那么(.)\\1+就是匹配重复出现的字符串一个或者多个
     */
    String reg = "(.)\\1+";
    String newStr = "$1";
    str = str.replaceAll(reg,newStr);
    System.out.println(str);
}

4)获取

    void match_str(String msgRlt){  
        String strReg =   
                "JSONSTART-([\\s\\S]*)-JSONEND";  
        Pattern pattern = Pattern.compile(strReg);  
        Matcher match = pattern.matcher(msgRlt);  

        // 如果匹配到内容,list添加数据  
        while (match.find()) {  
            String s = match.group(1);  
            if (!s.contains("-JSONENDJSONSTART-")) {  

                listRlt.add(s);  
            }else{  
                match_str("JSONSTART-" + s.substring(0, s.indexOf("-JSONENDJSONSTART-")+18));  
                match_str(s.substring(s.indexOf("-JSONENDJSONSTART-"), s.length()) + "-JSONEND");  
            }             
        }  
    }  

4,应用举例

1)检查字符串是否只包含数字的字符串

    public final static boolean isNumeric(String s) {  
        if (s != null && !"".equals(s.trim()))  
            return s.matches("^[0-9]*$");  
        else  
            return false;  
    }  

2)截取字符串中的数字字符串

    public static String cutOutNum(String s){

        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(s);
        s = m.replaceAll("");
        return s;
    }

猜你喜欢

转载自blog.csdn.net/SunshineTan/article/details/80741030