正则表达式

来源:互联网 发布:js和jsp交互 编辑:程序博客网 时间:2024/05/17 07:31

正则表达式

目录

  • 正则表达式
    • 目录
    • 正则表达式的规则
      • 字符
      • 字符类
      • 预定义字符类
      • POSIX 字符类仅 US-ASCII
      • javalangCharacter 类简单的 java 字符类型
      • Unicode 块和类别的类
      • 边界匹配器
      • Greedy 数量词贪婪模式
      • Reluctant 数量词勉强模式
      • Possessive 数量词 占有模式
      • Logical 运算符
    • 正则表达式的用法
      • 正则表达式的用法匹配字符串
      • 正则表达式的用法替换分割

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表通常被用来检索、替换那些符合某个模式(规则)的文本。(来源于百度百科)

正则表达式的规则

字符

表达 解释 x 字符 x \ 反斜线字符 \0n 带有八进制值0的字符 n (0 <= n <= 7) \0nn 带有八进制值 0 的字符 nn (0 <= n <= 7) \0mnn 带有八进制值0的字符mnn(0 <= m <= 3、0 <= n <= 7) \xhh 带有十六进制值0x的字符hh \uhhhh 带有十六进制值 0x 的字符hhhh \t 制表符 (‘\u0009’) \n 新行(换行)符 (‘\u000A’) \r 回车符 (‘\u000D’) \f 换页符 (‘\u000C’) \a 报警 (bell) 符 (‘\u0007’) \e 转义符 (‘\u001B’) \cx 对应于 x 的控制符

字符类

表达式 解释 [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](减去) [/u0041-/u0056] 汉字

预定义字符类

表达式 解释 . 任何字符(与行结束符可能匹配也可能不匹配) \d 数字:[0-9] \D 非数字: [^0-9] \s 空白字符:[ \t\n\x0B\f\r] \S 非空白字符:[^\s] \w 单词字符:[a-zA-Z_0-9] \W 非单词字符:[^\w]

POSIX 字符类(仅 US-ASCII)

表达式 解释 \p{Lower} 小写字母字符:[a-z] \p{Upper} 大写字母字符:[A-Z] \p{ASCII} 所有 ASCII:[\x00-\x7F] \p{Alpha} 字母字符:[\p{Lower}\p{Upper}] \p{Digit} 十进制数字:[0-9] \p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}] \p{Punct} 标点符号:!”#$%&’()*+,-./:;<=>?@[]^_`{ \p{Graph} 可见字符:[\p{Alnum}\p{Punct}] \p{Print} 可打印字符:[\p{Graph}\x20] \p{Blank} 空格或制表符:[ \t] \p{Cntrl} 控制字符:[\x00-\x1F\x7F] \p{XDigit} 十六进制数字:[0-9a-fA-F] \p{Space} 空白字符:[ \t\n\x0B\f\r]

java.lang.Character 类(简单的 java 字符类型)

表达式 解释 \p{javaLowerCase} 等效于 java.lang.Character.isLowerCase() \p{javaUpperCase} 等效于 java.lang.Character.isUpperCase() \p{javaWhitespace} 等效于 java.lang.Character.isWhitespace() \p{javaMirrored} 等效于 java.lang.Character.isMirrored()

Unicode 块和类别的类

表达式 解释 \p{InGreek} Greek 块(简单块)中的字符 \p{Lu} 大写字母(简单类别) \p{Sc} 货币符号 \P{InGreek} 所有字符,Greek 块中的除外(否定) [\p{L}&&[^\p{Lu}]] 所有字母,大写字母除外(减去)

边界匹配器

表达式 解释 ^ 行的开头 $ 行的结尾 \b 单词边界,就是非单词字符的地方 \B 非单词边界 \A 输入的开头 \G 上一个匹配的结尾 \Z 输入的结尾,仅用于最后的结束符(如果有的话) \z 输入的结尾

所谓的单词边界就是不能用\w全部匹配
举例:xiaoming\b
要匹配的字符xiaoming xiaoming222 xiaoming2()2
能匹配到的是第一个和第三个,因为第二个后面的全部都能用\w匹配。

Greedy 数量词(贪婪模式)

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

Greedy模式:即贪婪模式,此模式匹配字符时一直会匹配下去,直到无法匹配。

Reluctant 数量词(勉强模式)

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

每一个都比Greedy多一个?
勉强模式:匹配时是最小的字符。它与贪婪模式的对比如下。

public class GuiZeTest {public static void main(String[] args) {    String str = "aaa, bbb";    System.out.println(str.replaceFirst("\\w*", "+")); // +, bbb    System.out.println(str.replaceFirst("\\w*?", "+")); // +aaa, bbb    System.out.println(str.replaceFirst("\\w*+", "+"));}

}

Possessive 数量词 (占有模式)

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

每一个都比Greedy多一个+
占有模式:只有Java才有的模式,一般较少使用。

Logical 运算符

表达式 解释 XY X后跟Y X Y

正则表达式的用法

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

Pattern p = Pattern.compile("a*b");Matcher m = p.matcher("aaaaab");boolean b = m.matches();

Pattern compile(String regex)
将给定的正则表达式编译到模式中。
public Matcher matcher(CharSequence input)
创建一个匹配器,匹配给定的输入与此模式。
参数
input - 要匹配的字符序列
结果
这种模式的新匹配器
public static boolean matches(String regex CharSequence input)
编译给定的正则表达式,并尝试匹配给定的输入。
调用这种方便的方式的形式 Pattern.matches(regex, >input);表现方式与表达式完全相同
Pattern.compile(regex).matcher(input).matches()
如果一个模式多次被使用,编译一次并重用它将比每次调用此方法更有效。
参数
regex - 要编译的表达式
input - 要匹配的字符序列
结果
正则表达式是否匹配输入

由上文可知上面的三行代码可以写成:
boolean b = Pattern.matches("aaaaaab", "a*b")

正则表达式的用法:匹配字符串

import java.util.regex.*;public class FindGroup {public static void main(String[] args) {    String str = "这儿有一些电话号码,我只需要13和15开头的电话号码。" +            "13472011907,15189787288, 1789829828,1293141942";            Matcher m = Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);    while(m.find()) {        System.out.println(m.group());    }  }}

find() : 返回目标中是否与Pattern中匹配的字符串
group() : 返回上一次与Pattern匹配的字符串
start() : 返回上一次与Pattern匹配字符串的开始位置(在原字符串中)
end() : 返回上一次与Pattern匹配字符串的结束位置加1
lookAt() : 返回目标字符串与Pattern是否匹配,此方法与matches()比较相似,但不同的是它不需要匹配整个字符串。
reset : 重新设置需要匹配的字符串
matches() : 返回目标是否与Pattern是否匹配

下面是一些示例:

import java.util.regex.*;public class StartAndEnd {    public static void main(String[] args) {        String str = "Java is very easy";        System.out.println("目标字符串是:" + str);        Pattern p = Pattern.compile("\\w+");        Matcher m = p.matcher(str);        while(m.find()) {            System.out.println(m.group() + "起始位置:" + m.start() + "结束位置:" + m.end());        }    }}
import java.util.regex.*;public class MatchesTest {    public static void main(String[] args) {        String mails[] = {                "1293141942@qq.com",                "mengchen@xiyou3g.com",                "ppap@abbc.org",                "ascsc@cacs.asa"        };        String pattern = "\\w{3,20}@\\w+\\.(com|net|cn|org|gov)";        Pattern mp = Pattern.compile(pattern);        Matcher mm = null;        for(String mail : mails) {            if(mm == null) {                mm = mp.matcher(mail);            }            else {                mm.reset(mail);            }            System.out.println(mail + (mm.matches() ? "是" : "不是") + "一个邮箱地址。");        }    }}

事实上String中也提供了matches()方法
mials[0].matches("\\w{3,20}@\\w+\\.(com|net|cn|org|gov)")

正则表达式的用法:替换、分割

import java.util.regex.*;public class ReplaceTest {    public static void main(String[] args) {        String[] str = {                "Java is easy to study",                "I love Java",                "I don't konw to write something about Java"        };        Pattern p = Pattern.compile("Ja\\w+");        Matcher m = null;        for (String x : str) {            if (m == null) {                m = p.matcher(x);            }            else {                m.reset(x);            }            System.out.println(m.replaceAll("C语言"));        }    }}

Matcher类提供了替换字符串的方法
replaceAll():替换全部能匹配到的
replaceFirst() : 替换第一个匹配到的。
事实上,Java的String类也提供了这几个方法。

import java.util.Arrays;public class StringReplaceTest {    public static void main(String[] args) {        String[] str = {                "Java is easy to study",                "I love Java",                "I don't konw to write something about Java"        };        for(String x : str) {            System.out.println(x.replaceAll("java\\w+", "C语言"));            System.out.println(Arrays.toString(x.split(" ")));        }    }}
原创粉丝点击