Java正则表达式(Java Regular Expression)
来源:互联网 发布:中国食品出口数据 编辑:程序博客网 时间:2024/06/05 00:30
也不知道是谁首先将Regular Expression翻译成了"正则表达式"这么一个文诌诌的名词。无论是按字面还是按其用途,Regular Expression都应该是规则表达式,指对特定字符串构成规则/特征的描述。这种构成规则,也就是模式(Pattern)。
最早应用在Unix系统中的正则表达式尽管没有一个统一的权威标准,但各种正则表达式可说是大同、小异。
Java语言在JDK1.4版本中内置了java.util.regex,提供对正则表达式的支持, 其中包含Pattern、Matcher、PatternSyntaxException三个部分。
1. 正则表达式中的字符和字符集
构成字符串的最基本元素是字符,正则表达式中,字符可以是字母/数字等可打印字符,也可以是回车/换行等控制字符。
1.1 基本字符
1.2 字符类
Java正则表达式中,还可以用'[...]'的形式表示一类特定字符中的一个。如[abc],指a或b或c;[0-9]表示数字0到9中的某一个;[abc[lmn]]表示a|b|c|l|m|n。[^abc]表示除a/b/c外的其他任意字符;[a-z-[bcd]]则表示从[a-z]的集合中减掉集合[bcd]...。
Java中,提供了一些内置的预定义字符类,以方便使用。
POSIX字符类(仅应用于us-ascii)
边界字符
引用控制:
更多内置字符类, 可以在Java文档中java.util.regex.Pattern部分找到.
2. 逻辑操作符
Java提供了一些逻辑操作符,用来对字符/字符类进行简单的逻辑操作
3. 量词
量词,用来对模式的匹配数量进行限制.
3.1 基本量词
量词在应用时,总是会结合它左边的第一个模式. 如,模式abc+,会匹配abc, abcc, abccc..., 而不会匹配abcabc. 因此, 括号的使用在某些情况下是必要的.
3.2 量词匹配方式
Java中,提供了三种不同量词匹配方式.
- 贪婪型(Greedy) : 默认方式. 尽可能多地使用量词所修饰的模式去匹配字符串, 直至找到匹配为止
- 勉强型(Reluctant) : 最小匹配,尽可能少地使用量词所修饰模式去匹配字符串。在基本匹配量词后附加一个'?'标记使用此种方式
- 占用型(Possessive) : 占用量词所修饰模式所匹配的全部字符,将剩余部分留给模式的其他部分去匹配. 在基本匹配量词后附加一个'+'标记使用此种方式
假定要分析的字符串是xfooxxxxxxfoo
- 模式.*foo : 模式分为子模式p1(.*)和子模式p2(foo)两个部分. 其中p1中的量词匹配方式使用默认方式(贪婪型). 匹配开始时,吃入所有字符xfooxxxxxx去匹配子模式p1. 匹配成功,但这样以来就没有了字符串去匹配子模式p2. 本轮匹配失败;第二轮:减少p1部分的匹配量,吐出最后一个字符, 把字符串分割成xfooxxxxxxfo和o两个子字符串s1和s2. s1匹配p1, 但s2不匹配p2. 本轮匹配失败;第三轮,再次减少p1部分匹配量,吐出两个字符, 字符串被分割成xfooxxxxxxfo和oo两部分. 结果同上。第四轮,再次减少p1匹配量, 字符串分割成xfooxxxxxx和foo两个部分, 这次s1/s2分别和p1/p2匹配. 停止尝试,返回匹配成功.
- 模式.*?foo : 最小匹配方式. 第一次尝试匹配, p1由于是0或任意次,因此被忽略,用字符串去匹配p2,失败;第二次,读入第一个字符x, 尝试和p1匹配, 匹配成功; 字符串剩余部分fooxxxxxxfoo中前三个字符和p2也是匹配的. 因此, 停止尝试, 返回匹配成功.在这种模式下,如果对剩余字符串继续去寻找和模式相匹配的子字符串,还会找到字符串末尾的另一个xfoo,而在贪婪模式下,由于第一次匹配成功的子串就已经是所有字符,因此不存在第二个匹配子串。
- 模式.*+foo : 占用模式. 匹配开始时读入所有字符串, 和p1匹配成功, 但没有剩余字符串去和p2匹配. 因此, 匹配失败. 返回.
简单地说, 贪婪模式和占有模式相比, 贪婪模式会在只有部分匹配成功的条件下, 依次从多到少减少匹配成功部分模式的匹配数量, 将字符留给模式其他部分去匹配; 而占用模式则是占有所有能匹配成功部分, 绝不留给其他部分使用.
4. 匹配控制标志
在字符串匹配中,通常还需要注意大小写,换行风格(win下是\r\n,unix/linux则是\n), Unicode等等。Java正则表达式中,可以通过(?idmsux)设定或通过(?-idmsux)取消标志,方便用户自行控制。
5. 分组(Group)
分组, 即将将多个字符编组合在一起, 作为其他操作的一个逻辑单位. Java中, 以圆括号'(...)'作为分组的标识. 比如, 使用量词时,常会用到分组来指定要重复的单位.
Java正则表达式中, 分组可以分为捕获组(Capturing Group)和非捕获组(Non-Capturing Group)两类.
5.1 捕获组
实际应用中, 对字符串进行匹配操作时, 除了字符串是否匹配模式的答案外, 常常还会关心诸如字符串中有多少与模式相匹配的子串, 与模式相匹配的子串到底是什么样等更具体的问题. 某些情况下, 前面的捕获结果还会直接成为后面捕获模式的一部分. 这些都 需要在匹配过程中,将实际匹配的子串储存起来(也许还需要计数), 以供随后可能的使用.
Java正则表达式中, 默认分组都是捕获组, 也即分组模式匹配的结果会被缓存起来. 在存在多个分组的模式中, Java从左到右扫描模式中的括号, 依次给存在的分组进行编号.
0. ((A)(B(C))) 最外层括号所包含的模式。也即分组0永远都是模式本身。
1. (A) 从左向右,遇到第二个'('及相应')'构成的模式。
2. (B(C)) '('及相应')'构成的模式。
3. (C) '('及相应')'构成的模式。
除了在完成匹配后使用Java所缓存的结果外, 在匹配开始前就可以在匹配模式中通过'\i'的形式引用第i个分组可能匹配到的实际字符串. 这种引用模式被称为后置引用(Back Quote).
假如要匹配用成对单引号'或双引号"引用的字符串, 可以指定匹配模式为: (['"]).*\1。 模式匹配'abc', 或"abc"等,但不会匹配'abc"或"ab等字符串。
5.2 非捕获组
并非所有分组的匹配结果都必须缓存。以'(?...)'形式指定的分组被称为非捕获组。匹配过程中,非捕获组所匹配的实际内存不会被缓存,匹配数量也不会被统计。因此,非捕获组不会获得组编号,也不能被反向引用。
非捕获组的几种形式
如:(?:abc){3}匹配abcabcabc,但不缓存分组(abc)的匹配结果,更不能反向引用匹配结果(?=X)X为非捕获分组;并且,(?=X)匹配成功后不会占用任何字符!也即,形如(?=X)Y的模式中,子模式Y开始匹配的地方是非捕获组X匹配成功的开始处而不是结束处!
如:Jack(?=Sprat|Frost), 匹配字符串JackSprat中的Jack
\w+(?=\d)匹配任何以数字结尾的单词,返回结果不包含数字
(?=two)three不能匹配字符串onetwothree,(?=two)([a-z])则会匹配以上字符串中的tY(?!X)X为非捕获分组,模式匹配任何后面不是X的Y。
如: Jack(?!Sprat>匹配JackFrost,但不会匹配JackSrpat
\w+(?!\d)匹配任何不以数字结尾的单词,返回结果中不包含最后一个字符(?<=X)YX为非捕获分组,模式匹配前面有X的Y。如使用量词,则量词所指定重复次数必须是一个有限集合。如(?<=foo)bar匹配foobar中的bar
(?<=\w{2,3})\d匹配前面为2或3个单词字符的一位数字,如ab3中的3
(<=w+)\d非法,量词+可能匹配次数为无限。(?<!X)YX为非捕获分组,模式匹配前面不是X的Y。如使用量词,则量词所指定重复次数必须是一个有限集合。如(?<!20)10匹配任何不是以20开始的10(?>X)X为独立、非捕获分组。一旦X匹配成功,则不允许匹配引擎进行回退操作(贪婪模式下的吐字符)。
如:模式(?>[ab]*)\w\w,不能在字符串aabbaa中找到匹配子串。原因是(贪婪模式下)初次匹配时,[ab]*会将整个字符串占为己有,即使第一轮匹配失败也不会减少匹配量进行下一轮的尝试。而(?:[ab]*)\w\w)则可以匹配成功。
- java正则表达式; regular expression
- Java 正则表达式(Regular Expression)
- 正则表达式 java Regular Expression
- Java正则表达式(Java Regular Expression)
- Regular Expression 正则表达式-2 (Java)
- java正则表达式(Regular Expression)简单使用
- java正则表达式; regular expression(转)
- 调试工具系列--java 正则表达式(regular expression)调试工具
- Java正则表达式(Regular Expression) 邮箱验证
- 【regular expression】java,js,c++正则表达式比较
- Thinking in java-36 Regular expression正则表达式
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- 正则表达式(Regular Expression)
- 正则表达式(regular expression)
- 正则表达式 regular-expression
- 正则表达式(regular expression)
- 正则表达式(regular expression)
- Java 找数组中的元素
- 关于servlet的中的request和response两个对象的详细介绍
- linux引导流程
- 项目就像个受精卵,产品才是儿子
- 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)
- Java正则表达式(Java Regular Expression)
- java例程练习(多态/动态绑定/迟绑定)
- Exchange 2003 升级到Exchange 2010 设置OWA和网页重定向!
- 黑马程序员—SQL的学习
- 使用C#发送POST请求
- 判断页面是否第一件渲染
- 统计某字符串中某子串出现的次数
- 关于iBatis动态sql的生成
- "服务器不能完成你的请求。有关详细信息请单击‘详细信息按钮’"