A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© jannnonx 中级黑马   /  2016-6-18 00:34  /  470 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

正则表达式

一个正则表达式是一个用于文本搜索的文本模式。换句话说,在文本中搜索出现的模式。例如,你可以用正则表达式搜索网页中的邮箱地址或超链接。

正则表达式示例

下面是一个简单的Java正则表达式的例子,用于在文本中搜索 http://

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String pattern = ".*http://.*";boolean matches = Pattern.matches(pattern, text);System.out.println("matches = " + matches);

示例代码实际上没有检测找到的 http:// 是否是一个合法超链接的一部分,如包含域名和后缀(.com,.net 等等)。代码只是简单的查找字符串 http:// 是否出现。

Java6 中关于正则表达式的API

本教程介绍了Java6 中关于正则表达式的API。

Pattern (java.util.regex.Pattern)

类 java.util.regex.Pattern 简称 Pattern, 是Java正则表达式API中的主要入口,无论何时,需要使用正则表达式,从Pattern 类开始

Pattern.matches()

检查一个正则表达式的模式是否匹配一段文本的最直接方法是调用静态方法Pattern.matches(),示例如下:

String text    =        "This is the text to be searched " +        "for occurrences of the pattern.";String pattern = ".*is.*";boolean matches = Pattern.matches(pattern, text);System.out.println("matches = " + matches);

上面代码在变量 text 中查找单词 “is” 是否出现,允许”is” 前后包含 0或多个字符(由 .* 指定)

Pattern.matches() 方法适用于检查 一个模式在一个文本中出现一次的情况,或适用于Pattern类的默认设置。

如果需要匹配多次出现,甚至输出不同的匹配文本,或者只是需要非默认设置。需要通过Pattern.compile() 方法得到一个Pattern 实例。

Pattern.compile()

如果需要匹配一个正则表达式在文本中多次出现,需要通过Pattern.compile() 方法创建一个Pattern对象。示例如下

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString);

可以在Compile 方法中,指定一个特殊标志:

Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);

Pattern 类包含多个标志(int 类型),这些标志可以控制Pattern 匹配模式的方式。上面代码中的标志使模式匹配是忽略大小写

Pattern.matcher()

一旦获得了Pattern对象,接着可以获得Matcher对象。Matcher 示例用于匹配文本中的模式.示例如下

Matcher matcher = pattern.matcher(text);

Matcher类有一个matches()方法,可以检查文本是否匹配模式。以下是关于Matcher的一个完整例子

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(text);boolean matches = matcher.matches();System.out.println("matches = " + matches);Pattern.split()

Pattern 类的 split()方法,可以用正则表达式作为分隔符,把文本分割为String类型的数组。示例:

String text = "A sep Text sep With sep Many sep Separators";String patternString = "sep";Pattern pattern = Pattern.compile(patternString);String[] split = pattern.split(text);System.out.println("split.length = " + split.length);for(String element : split){    System.out.println("element = " + element);}

上例中把text 文本分割为一个包含5个字符串的数组。

Pattern.pattern()

Pattern 类的 pattern 返回用于创建Pattern 对象的正则表达式,示例:

String patternString = "sep";Pattern pattern = Pattern.compile(patternString);String pattern2 = pattern.pattern();

上面代码中 pattern2 值为sep ,与patternString 变量相同。

Matcher (java.util.regex.Matcher)

java.util.regex.Matcher 类用于匹配一段文本中多次出现一个正则表达式,Matcher 也适用于多文本中匹配同一个正则表达式。

Matcher 有很多有用的方法,详细请参考官方JavaDoc。这里只介绍核心方法。

以下代码演示如何使用Matcher

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(text);boolean matches = matcher.matches();

首先创建一个Pattern,然后得到Matcher ,调用matches() 方法,返回true 表示模式匹配,返回false表示不匹配。

可以用Matcher 做更多的事。

创建Matcher

通过Pattern 的matcher() 方法创建一个Matcher。

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(text);matches()

Matcher 类的 matches() 方法用于在文本中匹配正则表达式

boolean matches = matcher.matches();

如果文本匹配正则表达式,matches() 方法返回true。否则返回false。

matches() 方法不能用于查找正则表达式多次出现。如果需要,请使用find(), start() 和 end() 方法。

lookingAt()

lookingAt() 与matches() 方法类似,最大的不同是,lookingAt()方法对文本的开头匹配正则表达式;而

matches() 对整个文本匹配正则表达式。换句话说,如果正则表达式匹配文本开头而不匹配整个文本,lookingAt() 返回true,而matches() 返回false。 示例:

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = "This is the";Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(text);System.out.println("lookingAt = " + matcher.lookingAt());System.out.println("matches   = " + matcher.matches());

上面的例子分别对文本开头和整个文本匹配正则表达式 “this is the”. 匹配文本开头的方法(lookingAt()) 返回true。

对整个文本匹配正则表达式的方法 (matches()) 返回false,因为 整个文本包含多余的字符,而 正则表达式要求文本精确匹配”this is the”,前后又不能有额外字符。

find() + start() + end()

find() 方法用于在文本中查找出现的正则表达式,文本是创建Matcher时,通过 Pattern.matcher(text) 方法传入的。如果在文本中多次匹配,find() 方法返回第一个,之后每次调用 find() 都会返回下一个。

start() 和 end() 返回每次匹配的字串在整个文本中的开始和结束位置。实际上, end() 返回的是字符串末尾的后一位,这样,可以在把 start() 和 end() 的返回值直接用在String.substring() 里。

String text    =        "This is the text which is to be searched " +        "for occurrences of the word 'is'.";String patternString = "is";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(text);int count = 0;while(matcher.find()) {    count++;    System.out.println("found: " + count + " : "  + matcher.start() + " - " + matcher.end());}

这个例子在文本中找到模式 “is” 4次,输出如下:

found: 1 : 2 - 4 found: 2 : 5 - 7 found: 3 : 23 - 25 found: 4 : 70 - 72reset()

reset() 方法会重置Matcher 内部的 匹配状态。当find() 方法开始匹配时,Matcher 内部会记录截至当前查找的距离。调用 reset() 会重新从文本开头查找。

也可以调用 reset(CharSequence) 方法. 这个方法重置Matcher,同时把一个新的字符串作为参数传入,用于代替创建 Matcher 的原始字符串。

group()

假设想在一个文本中查找URL链接,并且想把找到的链接提取出来。当然可以通过 start()和 end()方法完成。但是用group()方法更容易些。

分组在正则表达式中用括号表示,例如:

(John)

此正则表达式匹配John, 括号不属于要匹配的文本。括号定义了一个分组。当正则表达式匹配到文本后,可以访问分组内的部分。

使用group(int groupNo) 方法访问一个分组。一个正则表达式可以有多个分组。每个分组由一对括号标记。想要访问正则表达式中某分组匹配的文本,可以把分组编号传入 group(int groupNo)方法。

group(0) 表示整个正则表达式,要获得一个有括号标记的分组,分组编号应该从1开始计算。

String text    =  "John writes about this, and John writes about that," +                        " and John writes about everything. "  ;String patternString1 = "(John)";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);while(matcher.find()) {    System.out.println("found: " + matcher.group(1));}

以上代码在文本中搜索单词John.从每个匹配文本中,提取分组1,就是由括号标记的部分。输出如下

found: John found: John found: John多分组

上面提到,一个正则表达式可以有多个分组,例如:

(John) (.+?)

这个表达式匹配文本”John” 后跟一个空格,然后跟1个或多个字符,最后跟一个空格。你可能看不到最后的空格。

这个表达式包括一些字符有特别意义。字符 点 . 表示任意字符。 字符 + 表示出现一个或多个,和. 在一起表示 任何字符,出现一次或多次。字符? 表示 匹配尽可能短的文本。

完整代码如下

String text    =          "John writes about this, and John Doe writes about that," +                  " and John Wayne writes about everything."        ;String patternString1 = "(John) (.+?) ";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);while(matcher.find()) {    System.out.println("found: " + matcher.group(1) +                       " "       + matcher.group(2));}

注意代码中引用分组的方式。代码输出如下

found: John writes found: John Doe found: John Wayne嵌套分组

在正则表达式中分组可以嵌套分组,例如

((John) (.+?))

这是之前的例子,现在放在一个大分组里.(表达式末尾有一个空格)。

当遇到嵌套分组时, 分组编号是由左括号的顺序确定的。上例中,分组1 是那个大分组。分组2 是包括John的分组,分组3 是包括 .+? 的分组。当需要通过groups(int groupNo) 引用分组时,了解这些非常重要。

以下代码演示如何使用嵌套分组

String text    =          "John writes about this, and John Doe writes about that," +                  " and John Wayne writes about everything."        ;String patternString1 = "((John) (.+?)) ";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);while(matcher.find()) {    System.out.println("found:   ");}

输出如下

found:  found:  found:

1 个回复

倒序浏览
好详细啊谢谢楼主,辛苦了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马