本文共 3061 字,大约阅读时间需要 10 分钟。
正则表达式(regular expression)用于指定字符串的模式,你可以在任何需要定位匹配某种特定模式的字符串的情况下使用正则表达式。例如,我们有一个示例程序就是用来定位HTML文件中的所有超链接的,它是通过查找模式的字符串来实现此目的的。
当然,在指定模式时,...标记法并不够精确。你需要精确地指定什么样的字符序列才是合法的匹配,这就要求无论何时,当你要描述一个模式时,都需要使用某种特定的语法。下面是一个简单的示例,正则表达式匹配下列形式的所有字符串:
例如,字符串“javanese”就匹配这个特定的正则表达式,但是字符串“core java”就不匹配。
正如你所见,你需要了解一点这种语法,以理解正则表达式的含义。幸运的是,对于大多数情况,一小部分很直观的语法结构就足够用了。例如,字符串cab匹配[a-z]ab,但是不匹配[a-z]+ab。在第一种情况中,表达式[a-z]只匹配字符c,使得字符ab匹配该模式的剩余部分;但是贪婪版本[a-z]+将匹配字符cab,模式的剩余部分将无法匹配。
例如,下面是一个有些复杂但是却可能很有用的正则表达式,它描述了十进制和十六进制整数:
遗憾的是,在使用正则表达式的各种程序和类库之间,表达式语法并未完全标准化。尽管在基本结构上达成了一致,但是它们在细节上仍旧存在着许多令人抓狂的差异。Java正则表达式类使用的语法与Perl语言使用的语法十分相似,但是并不完全一样。表2-6展示的是Java语法中的所有结构。关于正则表达式语法的更多信息,可以求教于Pattern类的API文档和Jeffrey E. F. Friedl的《Mastering Regular Expressions》(O’Reilly and Associates, 2006)。
正则表达式的最简单用法就是测试某个特定的字符串是否与它匹配。下面展示了如何用Java来编写这种测试,首先用表示正则表达式的字符串构建一个Pattern对象。然后从这个模式中获得一个Matcher,并调用它的matches方法:这个匹配器的输入可以是任何实现了CharSequence接口的类的对象,例如String、StringBuilder和CharBuffer。
在编译这个模式时,你可以设置一个或多个标志,例如:下面是各个标志。
最后两个标志不能在正则表达式内部指定。
如果想要在集合或流中匹配元素,那么可以将模式转换为谓词:那么,匹配器会报告下面的群组:
程序清单2-6的程序提示输入一个模式,然后提示输入用于匹配的字符串,随后将打印出输入是否与模式相匹配。如果输入匹配模式,并且模式包含群组,那么这个程序将用括号打印出群组边界,例如
程序清单2-6 regex/RegexTest.java
通常,你不希望用正则表达式来匹配全部输入,而只是想找出输入中一个或多个匹配的子字符串。这时可以使用Matcher类的f?ind方法来查找匹配内容,如果返回true,再使用start和end方法来查找匹配的内容,或使用不带引元的group方法来获取匹配的字符串。
程序清单2-7对这种机制进行了应用,它定位一个Web页面上的所有超文本引用,并打印它们。为了运行这个程序,你需要在命令行中提供一个URL,例如
程序清单2-7 match/HrefMatch.java
Matcher类的replaceAll方法将正则表达式出现的所有地方都用替换字符串来替换。例如,下面的指令将所有的数字序列都替换成#字符。
替换字符串可以包含对模式中群组的引用:$n表示替换成第n个群组,${name}被替换为具有给定名字的组,因此我们需要用$来表示在替换文本中包含一个$字符。
如果字符串中包含$和,但是又不希望它们被解释成群组的替换符,那么就可以调用matcher.replaceAll(Matcher.quoteReplacement(str))。replaceFirst方法将只替换模式的第一次出现。最后,Pattern类有一个split方法,它可以用正则表达式来匹配边界,从而将输入分割成字符串数组。例如,下面的指令可以将输入分割成标记,其中分隔符是由可选的空白字符包围的标点符号。如果有多个标记,那么可以惰性地获取它们:
如果不关心预编译模式和惰性获取,那么可以使用String.split方法:
转载地址:http://auudl.baihongyu.com/