《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一2.7 正则表达式

简介: 本节书摘来华章计算机《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一书中的第2章 ,第2.7节,[美] 凯S.霍斯特曼(Cay S. Horstmann) 著陈昊鹏 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.7 正则表达式

正则表达式(regular expression)用于指定字符串的模式,你可以在任何需要定位匹配某种特定模式的字符串的情况下使用正则表达式。例如,我们有一个示例程序就是用来定位HTML文件中的所有超链接的,它是通过查找image模式的字符串来实现此目的的。
当然,在指定模式时,...标记法并不够精确。你需要精确地指定什么样的字符序列才是合法的匹配,这就要求无论何时,当你要描述一个模式时,都需要使用某种特定的语法。
下面是一个简单的示例,正则表达式
image

匹配下列形式的所有字符串:

  • 第一个字母是J或j。
  • 接下来的三个字母是ava。
  • 字符串的其余部分由一个或多个任意的字符构成。

例如,字符串“javanese”就匹配这个特定的正则表达式,但是字符串“core java”就不匹配。
正如你所见,你需要了解一点这种语法,以理解正则表达式的含义。幸运的是,对于大多数情况,一小部分很直观的语法结构就足够用了。

  • 字符类(character class)是一个括在括号中的可选择的字符集,例如,[Jj]、[0-9]、[A-Za-z]或1。这里“-”表示是一个范围(所有Unicode值落在两个边界范围之内的字符),而 ^ 表示补集(除了指定字符之外的所有字符)。
  • 如果字符类中包含“-”,那么它必须是第一项或最后一项;如果要包含“[”,那么它必须是第一项;如果要包含“^”,那么它可以是除开始位置之外的任何位置。其中,你只需要转义“[”和“”。
  • 有许多预定的字符类,例如d(数字)和p{Sc}(Unicode货币符号)。请查看表2-6和表2-7。

image
image
image

image

  • 大部分字符都可以与它们自身匹配,例如在前面示例中的ava字符。
    .符号可以匹配任何字符(有可能不包括行终止符,这取决于标志的设置)。
  • 使用作为转义字符,例如,.匹配句号而\匹配反斜线。
  • ^和$分别匹配一行的开头和结尾。
  • 如果X和Y是正则表达式,那么XY表示“任何X的匹配后面跟随Y的匹配”,X | Y表示“任何X或Y的匹配”。
  • 你可以将量词运用到表达式X:X+(1个或多个)、X*(0个或多个)与X?(0个或1个)。
  • 默认情况下,量词要匹配能够使整个匹配成功的最大可能的重复次数。你可以修改这种行为,方法是使用后缀?(使用勉强或吝啬匹配,也就是匹配最小的重复次数)或使用后缀+(使用占有或贪婪匹配,也就是即使让整个匹配失败,也要匹配最大的重复次数)。

例如,字符串cab匹配[a-z]ab,但是不匹配[a-z]+ab。在第一种情况中,表达式[a-z]只匹配字符c,使得字符ab匹配该模式的剩余部分;但是贪婪版本[a-z]+将匹配字符cab,模式的剩余部分将无法匹配。

  • 我们使用群组来定义子表达式,其中群组用括号()括起来。例如,([+-]?)([0-9]+)。然后你可以询问模式匹配器,让其返回每个组的匹配,或者用n来引用某个群组,其中n是群组号(从1开始)。
    image

例如,下面是一个有些复杂但是却可能很有用的正则表达式,它描述了十进制和十六进制整数:
image

遗憾的是,在使用正则表达式的各种程序和类库之间,表达式语法并未完全标准化。尽管在基本结构上达成了一致,但是它们在细节上仍旧存在着许多令人抓狂的差异。Java正则表达式类使用的语法与Perl语言使用的语法十分相似,但是并不完全一样。表2-6展示的是Java语法中的所有结构。关于正则表达式语法的更多信息,可以求教于Pattern类的API文档和Jeffrey E. F. Friedl的《Mastering Regular Expressions》(O’Reilly and Associates, 2006)。
正则表达式的最简单用法就是测试某个特定的字符串是否与它匹配。下面展示了如何用Java来编写这种测试,首先用表示正则表达式的字符串构建一个Pattern对象。然后从这个模式中获得一个Matcher,并调用它的matches方法:
image

这个匹配器的输入可以是任何实现了CharSequence接口的类的对象,例如String、StringBuilder和CharBuffer。
在编译这个模式时,你可以设置一个或多个标志,例如:
image

下面是各个标志。

  • Pattern.CASE_INSENSITIVE或r:匹配字符时忽略字母的大小写,默认情况下,这个标志只考虑US ASCII字符。
  • Pattern.UNICODE_CASE或u:当与CASE_INSENSITIVE组合使用时,用Unicode 字母的大小写来匹配。
  • Pattern.UNICODE_CHARACTER_CLASS或U:选择Unicode字符类代替POSIX,其中蕴含了UNICODE_CASE。
  • Pattern.MULTILINE或m:^和$匹配行的开头和结尾,而不是整个输入的开头和结尾。
  • Pattern.UNIX_LINES或d:在多行模式中匹配^和$时,只有'n'被识别成行终
    止符。
  • Pattern.DOTALL或s:当使用这个标志时,. 符号匹配所有字符,包括行终止符。
  • Pattern.COMMENTS或x:空白字符和注释(从#到行末尾)将被忽略。
    Pattern.LITERAL:该模式将被逐字地采纳,必须精确匹配,因字母大小写而造成的差异除外。
  • Pattern.CANON_EQ:考虑Unicode字符规范的等价性,例如,u后面跟随¨(分音符号)匹配ü。

最后两个标志不能在正则表达式内部指定。
如果想要在集合或流中匹配元素,那么可以将模式转换为谓词:

image

那么,匹配器会报告下面的群组:
 image

程序清单2-6的程序提示输入一个模式,然后提示输入用于匹配的字符串,随后将打印出输入是否与模式相匹配。如果输入匹配模式,并且模式包含群组,那么这个程序将用括号打印出群组边界,例如
image

程序清单2-6 regex/RegexTest.java
image
image

通常,你不希望用正则表达式来匹配全部输入,而只是想找出输入中一个或多个匹配的子字符串。这时可以使用Matcher类的f?ind方法来查找匹配内容,如果返回true,再使用start和end方法来查找匹配的内容,或使用不带引元的group方法来获取匹配的字符串。
image

程序清单2-7对这种机制进行了应用,它定位一个Web页面上的所有超文本引用,并打印它们。为了运行这个程序,你需要在命令行中提供一个URL,例如
image

程序清单2-7 match/HrefMatch.java
image
image

Matcher类的replaceAll方法将正则表达式出现的所有地方都用替换字符串来替换。例如,下面的指令将所有的数字序列都替换成#字符。
image

替换字符串可以包含对模式中群组的引用:$n表示替换成第n个群组,${name}被替换为具有给定名字的组,因此我们需要用$来表示在替换文本中包含一个$字符。
如果字符串中包含$和,但是又不希望它们被解释成群组的替换符,那么就可以调用matcher.replaceAll(Matcher.quoteReplacement(str))。
replaceFirst方法将只替换模式的第一次出现。
最后,Pattern类有一个split方法,它可以用正则表达式来匹配边界,从而将输入分割成字符串数组。例如,下面的指令可以将输入分割成标记,其中分隔符是由可选的空白字符包围的标点符号。
image

如果有多个标记,那么可以惰性地获取它们:
image

如果不关心预编译模式和惰性获取,那么可以使用String.split方法:
image

image
image
image


  1. 0-9
相关文章
|
1月前
|
开发框架 Java API
最新Java基础系列课程--Day13-高级特性(二)
最新Java基础系列课程--Day13-高级特性
|
2月前
|
数据采集 Java 数据格式
【Java】正则表达式,校验数据格式的合法性。
【Java】正则表达式,校验数据格式的合法性。
44 0
|
2月前
|
机器学习/深度学习 存储 JavaScript
正则表达式基础语法与Java、JS使用实例
正则表达式基础语法与Java、JS使用实例
61 1
|
1月前
|
Java 程序员 API
最新Java基础系列课程--Day13-高级特性(三)
最新Java基础系列课程--Day13-高级特性
|
1月前
|
开发框架 Java 程序员
最新Java基础系列课程--Day13-高级特性(一)
最新Java基础系列课程--Day13-高级特性
|
2月前
|
Java 计算机视觉
【Java 正则表达式】简单用法,注意点,我学不会正则
【Java 正则表达式】简单用法,注意点,我学不会正则
|
2月前
|
开发框架 Java 程序员
最新Java基础系列课程--Day13-高级特性
最新Java基础系列课程--Day13-高级特性
|
2月前
|
Java
Java正则表达式【详解】
Java正则表达式【详解】
29 1
|
2月前
|
存储 Java 编译器
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记(下)
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记
78 0
|
2月前
|
存储 自然语言处理 Java
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记(上)
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记
76 0