`
thihy
  • 浏览: 69063 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java正则表达式进阶教程之构造方法

阅读更多

原文发于http://blog.thihy.info/post/119转载请注明出处。

本文是在学习正则表达式过程中整理的,虽然冠以“教程”,但实际上应该算是学习笔记。整篇文章需要对正则有一定的理解。。如果有啥写得不对的,或者写得不够清楚的,欢迎大家留言讨论。

概述

正则表达式(Regular Expression)是高效的、便捷的文本处理工具,能够快速查询符合某种规范的文本。

例如:[0-9]{3}可以匹配3位数字,[a-z]{3}则可以匹配3个小写字母。

目前正则表达式被众多工具所支持,比如egrep、sed、perl、ruby、Java、C#、python、Tcl等,不同的工具下,正在表达式的范式可能会有略微的差别,执行引擎也可能不同。目前,正则引擎主要有:DFA, 传统型NFA, POSIX NFA, DFA/NFA混合。本文主要介绍Java正则表达式,它的引擎属于传统型NFA。

Java正则支持Unicode,它在适当的时候,会使用java.lang.Character.codePointAt(CharSequence seq, int index)获取Code Point,而不是char。

构造方法

Java中的正则表达式的构造方法可以看Pattern的javadoc文档。

字符

对于可见字符,可以直接编写,这没啥难点。对于其它难以描述的字符,Java提供了一些表示方法。

字符缩略表示法

Java执行使用\x来代表特殊的含义,有:

\\
反斜线字符
\t
制表符 (‘\u0009′)
\n
新行(换行) 符 (‘\u000A’)
\r
回车符 (‘\u000D’)
\f
换页符 (‘\u000C’)
\a
报警(bell)符 (‘\u0007′)
\e
转义符 (‘\u001B’)
\v
垂直制表符 (‘\u000B’)

控制字符: \cchar

Java可以使用\cchar匹配控制字符。其中char的值为64 ^ 控制字符,比如对于退格符(‘\b‘),其ASCII码为8,则char64 ^ 8 = 72,也即H(H的ASCII码为72)。简单地,对于ASCII码小于64的控制字符,char为控制字符的ASCII码加上64。

八进制表示:\0n\0nn\0mnn

Java中,八进制表示必须以\0开始(防止与反向引用混淆),这点可能与其他工具不同(某些工具有规则来区分反向引用和八进制)。\0后面的部分最多只能有3个数字,而n必须在区间[0,7]内,m必须在[0,3]内,所以最大表示\0377。

十六进制表示:\xhh

十六进制后面必须是两个十六进制字符,也即h必须是0~9,a-f或A-F。\x00和\xff都是合法的,但是\xa,\x0ab,\x1g都是不合法的。

Unicode转义:\uhhhh

Unicode转义的形式与十六进制类似,只是后面必须是四个六进制字符。

行结束符

行结束符是用来标记输入字符序列的行结尾,可能有一个或两个字符。在Java中,行结束符包括:

  • 新行(换行)符 (‘\n’)
  • 后面紧跟新行符的回车符 (“\r\n”)
  • 单独的回车符 (‘\r’)
  • 下一行字符 (‘\u0085′)
  • 行分隔符 (‘\u2028′)
  • 段落分隔符 (‘\u2029)

如果启用了UNIX_LINES模式,则新行符(即’\n’)是惟一识别的行结束符。

只有启用DOTALL标志,正则表达式中的点号(即’.')才会匹配行结束符。

默认情况下,正则表达式^和$会忽略行结束符,仅分别与整个输入序列的开头和结尾匹配。如果激活 MULTILINE 模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配。处于 MULTILINE 模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配。

字符类

字符类: [...]

字符类的形式是[...],其内部可以是若干字符,也可以是一个字符范围。比如[a]表示匹配a字符,[a-z]表示匹配所有小写的英文字母。字符范围中的字符可以是Unicode字符,并且不要求是同一类的,也即[a-}]也是可以的,甚至是[a-星]

字符类集合运算

字符类可以进行补集、并集(隐式)、交集和差集的运算。所有的集合运算都必须在字符类内部实现

补集
如果字符类中以^开头,则表示是一个补集。比如[^a]表示匹配不是a的所有字符,这与[a^]是不同的,后者表示匹配a字符或^字符。既然是补集,那么需要明确全集是什么。由于Java是支持Unicode的,所以全集是所有的Unicode字符。也即[^a]可以匹配汉字字符。注:很多书籍上(包括JavaDoc)都没有谈到补集的概念,而是作为基本的字符类,但我觉得成为补集操作更加便于理解。
并集
可以在字符类中以字符类的方式来进行并集操作,比如对于[123456],可以表示为[123[456]]、[[123][456]、[[1][2][3][4][5][6]]、[[1[2]][3][4[5]6]]。并集操作时隐式的,没有特别的操作符,只需要按次序排在一起就OK了。
交集
交集操作可以保留两个字符类的共同部分,它要求两个字符类之间添加交集运算符&&。例如[[1-5]&&[3-9]]等价于[3-5]。通过环视功能可以模拟交集运算,比如(?=[1-5])[3-9][3-9](?<=[1-5])都等价于[3-5]。
差集
Java本身不支持差集元算,但是通过交集+补集的形式来实现。比如[[0-9] && [^3-5]]等价于[0-26-9]。同样,也可以通过环视功能来模拟差集,比如(?![3-5])[0-9][0-9](?<![3-5])都等价于[0-26-9]。

Java在解析字符类时,会按照如下的次序依次执行:

  1. 字面值转义 \x
  2. 分组 [...]
  3. 范围 a-z
  4. 并集 [a-e][i-u]
  5. 交集 [a-z&&[aeiou]]
  6. 补集 [^...]

点号:.

点号可以用来匹配除了行结束符之外的任意字符。但是,如果启用了DOTALL标志,则可以匹配行结束符

1
2
3
// (?s)会启用DOTALL标志
assertEquals(true"\n".matches("(?s)."));
assertEquals(true"\r".matches("(?s)."));

字符类简记法:

Java预定义了如下几种字符组,可以很方便地使用。

  • \d 数字:[0-9]
  • \D 非数字:[^0-9]
  • \s 空白字符:[ \t\n\x0B\f\r] (注意第一个字符是空格)
  • \S 非空白字符:[^\s]
  • \w 单词字符:[a-zA-Z_0-9]
  • \W 非单词字符:[^\w]

Unicode属性和区块:\p{PropOrBlock\P{PropOrBlock

\p{PropOrBlock表示匹配符合PropOrBlock的所有字符,大写的\P{PropOrBlock则匹配不符合PropOrBlock的所有字符。

PropOrBlock包括字符属性(Char Property)和区块(Block)。区块必须In开头,字符属性可以以Is开头(可选)。Unicode 区块的定义在java.lang.Character.UnicodeBlock,具体可以查看Unicode标准。字符属性的定义在java.util.regex.Pattern.CharPropertyNames

部分Unicode区块列表(查看WIKI) 属性 说明
\p{InBASIC_LATIN} Basic Latin
\p{InCJK_COMPATIBILITY} 中日韩兼容文字
更多请查看JavaDoc
基本的POSIX字符属性表(查看标准定义) 属性 说明
\p{ASCII} ASCII字符: 0×00~0x7F
\p{Lower} 小写字母([a-z])
\p{Upper} 小写字母([A-Z])
\p{Punct} ASCII标点符号
\p{Alpha} ASCII字母([a-zA-Z])
\p{Digit} 数字([0-9]
\p{Alnum} ASCII字母和数字: [a-zA-Z0-9])
\p{Graph} ASCII可打印(可见)字符: [\p{Alnum}\p{Punct}]
\p{Blank} ASCII Blank字符(空格和Tab字符)
\p{Cntrl} ASCII控制字符([\x00-\x1F\x7F])
\p{Print} 可打印字符(0×20~0x7E)
\p{Space} ASCII Space字符([ \t\n\x0B\f\r])
\p{XDigit} ASCII十六进制字符([0-9a-fA-F])
Java补充的字符属性表(定义于Character类) 属性 说明
\p{javaLowerCase} 等效于 java.lang.Character.isLowerCase()
\p{javaUpperCase} 等效于 java.lang.Character.isUpperCase()
\p{javaTitleCase} 等效于 java.lang.Character.isTitleCase()
\p{javaDigit} 等效于 java.lang.Character.isDigit()
\p{javaDefined} 等效于 java.lang.Character.isDefined()
\p{javaLetter} 等效于 java.lang.Character.isLetter()
\p{javaLetterOrDigit} 等效于 java.lang.Character.isLetterOrDigit()
\p{javaJavaIdentifierStart} 等效于 java.lang.Character.isJavaIdentifierStart()
\p{javaJavaIdentifierPart} 等效于 java.lang.Character.isJavaIdentifierPart()
\p{javaUnicodeIdentifierStart} 等效于 java.lang.Character.isUnicodeIdentifierStart()
\p{javaUnicodeIdentifierPart} 等效于 java.lang.Character.isUnicodeIdentifierPart()
\p{javaIdentifierIgnorable} 等效于 java.lang.Character.isIdentifierIgnorable()
\p{javaSpaceChar} 等效于 java.lang.Character.isSpaceChar()
\p{javaISOControl} 等效于 java.lang.Character.isISOControl()
\p{javaWhitespace} 等效于 java.lang.Character.isWhitespace()
\p{javaMirrored} 等效于 java.lang.Character.isMirrored()
Unicode字符属性表(查看标准定义) 属性 说明
\p{L} Letter: 字母
\p{M} Mark: 标记字符,不能单独出现,必须与其他基本字符同时出现(如重音符号)。
\p{N} Number: 各种数字字符
\p{Z} Separator: 分隔字符,但是本身不可见(比如空格)
\p{P} Punctuation: 标点符号
\p{S} Symbol: 各种图形符号和字母符号
\p{C} Other: 其他任何字符
\p{Ll} Character.LOWERCASE_LETTER: 小写字母
\p{Lu} Character.UPPERCASE_LETTER: 大写字母
\p{Lt} Character.TITLECASE_LETTER: 出现在单词开头的字母
\p{Lm} Character.MODIFIER_LETTER: 少数形似字母的,有特别用途的字符
\p{Lo} Character.OTHER_LETTER: 没有大小写形式,也不属于修饰符的字母。
\p{LC} L1,Lu,Lt
\p{LD} LC,Lm,Lo,Nd
\p{L1} Latin-1(0×00~0xff)
\p{Mn} Character.NON_SPACING_MARK
\p{Mc} Character.COMBINING_SPACING_MARK
\p{Me} Character.ENCLOSING_MARK
\p{Nd} Character.DECIMAL_DIGIT_NUMBER
\p{Nl} Character.LETTER_NUMBER
\p{No} Character.OTHER_NUMBER
\p{Zs} Character.SPACE_SEPARATOR
\p{Zl} Character.LINE_SEPARATOR
\p{Zp} Character.PARAGRAPH_SEPARATOR
p{Cc} Character.CONTROL
p{Cf} Character.FORMAT
p{Co} Character.PRIVATE_USE
p{Cs} Character.SURROGATE
p{Pd} Character.DASH_PUNCTUATION
p{Ps} Character.START_PUNCTUATION
p{Pe} Character.END_PUNCTUATION
p{Pc} Character.CONNECTOR_PUNCTUATION
p{Po} Character.OTHER_PUNCTUATION
p{Sm} Character.MATH_SYMBOL
p{Sc} Character.CURRENCY_SYMBOL
p{Sk} Character.MODIFIER_SYMBOL
p{So} Character.OTHER_SYMBOL
p{Pi} Character.INITIAL_QUOTE_PUNCTUATION
p{Pf} Character.FINAL_QUOTE_PUNCTUATION
p{all} 所有字符

锚点及其他“零长度断言”

锚点及其他“零长度断言”都是用来匹配一个位置,而不是具体的字符。

起始位置:^、\A

脱字符(^)和\A会匹配输入文本的起始位置。但是如果启用了MULTILINE模式,^还可以匹配每个行结束符之后的位置。

 
// \A会匹配起始位置
assertEquals(true"abcde".matches("\\Aabcde"));
// MULTILINE模式下,\A仍然只匹配起始位置,而不会匹配行结束符之后的位置!
assertEquals(false"\nabcde".matches("(?m)\n\\Aabcde"));
 
// ^ 会匹配起始位置
assertEquals(true"abcde".matches("^abcde"));
// MULTILINE模式下,^会匹配行结束符之后的位置!
assertEquals(true"\nabcde".matches("(?m)\n^abcde"));
// 甚至这样
assertEquals(true"\na\nbcde".matches("(?m)\n^a\n^bcde"));

结束位置:$、\Z和\z

$比较复杂,它的含义依赖于MULTILINE模式是否启用。再次明确一下,行结束符会根据UNIX_LINES模式是否启用而变化。

  • 未启用MULTILINE模式(默认)
    $待匹配位置之后要么没有任意字符(即严格的结尾),要么只是行结束符,但需要要注意的是,在非UNIX_LINES模式下,它不能在\r\n之间。
     
    // 匹配严格的结尾
    assertEquals(true"abcde".matches("abcde$"));
    // 匹配严格的结尾
    assertEquals(true"abcde\r".matches("abcde\r$"));
    assertEquals(true"abcde\r\n".matches("abcde\r\n$"));
    // 匹配行结束符之前的位置
    assertEquals(true"abcde\r".matches("abcde$\r"));
    assertEquals(true"abcde\n".matches("abcde$\n"));
    assertEquals(true"abcde\u0085".matches("abcde$\u0085"));
    assertEquals(true"abcde\u2028".matches("abcde$\u2028"));
    assertEquals(true"abcde\u2029".matches("abcde$\u2029"));
    assertEquals(true"abcde\r\n".matches("abcde$\r\n"));   
    // 启用UNIX_LINES模式后,行结束符只有\n
    assertEquals(false"abcde\r".matches("(?d)abcde$\r"));
    assertEquals(true"abcde\n".matches("(?d)abcde$\n"));
    assertEquals(false"abcde\u0085".matches("(?d)abcde$\u0085"));
    assertEquals(false"abcde\u2028".matches("(?d)abcde$\u2028"));
    assertEquals(false"abcde\u2029".matches("(?d)abcde$\u2029"));
    assertEquals(false"abcde\r\n".matches("(?d)abcde$\r\n"));
    // 启用UNIX_LINES模式后,$可以在\r\n之间
    assertEquals(true"abcde\r\n".matches("(?d)abcde\r$\n"));
    // 还可以这样匹配
    assertEquals(true"abcde\r\r\n".matches("abcde\r$\r\n"));
    assertEquals(true"abcde\n\r\n".matches("abcde\n$\r\n"));
    // 甚至是这样
    assertEquals(true"abcde\r\n".matches("abcde$\r\n$"));
    assertEquals(true"abcde\r\n".matches("abcde$$\r\n$$"));
    // 但不能匹配
    assertEquals(false"abcde\r\n".matches("abcde\r$\n"));// 不能匹配\r\n之间的位置
    assertEquals(false"abcde\r\n\n".matches("abcde\r$\n\n"));// 不能匹配\r\n之间的位置
    assertEquals(false"abcde\n\n".matches("abcde$\n$\n$"));// 第一个$不满足条件
  • 启用MULTILINE模式
    $能够匹配输入文本的严格末尾,或者行结束符之前的位置,需要注意的是,在非UNIX_LINES模式下,它同样不能在\r\n之间。
     
    // 非MULTILINE模式下的所有正则表达式,它都可以匹配成功。
    // 但是从下面这个断言可以看出区别
    assertEquals(true"abcde\n\n".matches("(?m)abcde$\n$\n$"));// 第一个$也满足条件

其实MULTILINE模式的启用只是允许$匹配文本中间的行(要不也不叫多行模式了)。

\Z等价于未启用MULTILINE模式的$。

 
// 与未启用MULTILINE模式的$一样
assertEquals(true"abcde".matches("(?m)abcde\\Z"));
assertEquals(true"abcde\n".matches("(?m)abcde\\Z\n"));
// 即使正则表达式启用了MULTILINE模式,也不能匹配成功
assertEquals(false"abcde\n\n".matches("(?m)abcde\\Z\n\\Z\n\\Z"));

\z则匹配输入文本的严格末尾,也即要求待匹配位置后面不能有任何字符(包括行结束符)。

 
// 匹配末尾
assertEquals(true"abcde\n".matches("abcde\n\\z"));
// 后面不能有任何字符,所以不能匹配
assertEquals(false"abcde\n".matches("abcde\\z\n"));

上次匹配成功的结束位置:\G

在迭代匹配中,有时候需要从上次匹配成功的结束位置继续匹配,就跟循环执行\A一样。

在每次成功匹配之后,Java会保存此次匹配的结束位置(见Matcher.last)。下次匹配时,如果上次起始位置与上次结束位置一样,则强制前进一个字符,防止无穷循环。如果要求匹配\G,则会比较当前的位置是否与上次结束位置相同,相同则匹配成功,否则匹配不成功。

1
assertEquals("!a!b!c!d!e!""abcde".replaceAll("x?""!"));

单词分界符:\b、\B

单词分界符\b用来匹配单词的边界,边界要求一边是单词字母,另一边不是单词字母。所谓单词字母,包括下划线(‘_’)、大小写字母、数字和非空格标记字符(Character.NON_SPACING_MARK),也即[\w\p{Mn}]。

\B则匹配不是单词边界的位置。

Java不区分左分界、右分界,而是笼统的边界。可以使用下面介绍的环视功能来区分左右边界,比如(?

顺序环视(?=…)、(?!…);逆序环视(?<=…)、(?<!…)

环视功能可以从当前位置向左或向右匹配执行的正则子表达式。向左查看称作逆序环视,向右查看称作顺序环视。

举例说明,对于字符串1234223432344234,(?<=2)234可以匹配到1234223432344234。

逆序环视要求长度是确定的,也即最大长度不能使无穷的。比如(?<=books?)是可以的,因为其最大长度是5,但(?<=\w+)是不行的。

注释和模式修饰符

模式修饰符:(?modifier),如(?i)和(?-i)

Java允许在正则表达式中使用模式修饰符来设定匹配模式,(?x)开启x模式,(?-x)关闭x模式。如果模式修饰符在括号内部,则其作用范围仅限于括号内部。

比如<B>(?i)text(?-i)</B>,要求两边的TAG必须为大写,而启用的内容text则不关系大小写。<B>(?:(?i)text)</B>也是相同的含义,因为(?i)只作用于括号内部。

 
// <B>(?i)text(?-i)</B>
assertEquals(true"<B>text</B>".matches("<B>(?i)text(?-i)</B>"));
assertEquals(true"<B>TEXT</B>".matches("<B>(?i)text(?-i)</B>"));
assertEquals(false"<b>text</B>".matches("<B>(?i)text(?-i)</B>"));
 
// <B>(?:(?i)text)</B>
assertEquals(true"<B>text</B>".matches("<B>(?:(?i)text)</B>"));
assertEquals(true"<B>TEXT</B>".matches("<B>(?:(?i)text)</B>"));
assertEquals(false"<b>text</B>".matches("<B>(?:(?i)text)</B>"));
模式修饰符字母列表 字母 模式
i 对应于Pattern.CASE_INSENSITIVE标志: 不区分大小写
d 对应于Pattern.UNIX_LINES标志:只有\n被视为行结束符,\r等不再被视为行结束符
u 对应于Pattern.UNICODE_CASE标志:当启用CASE_INSENSITIVE模式时,忽略大小写时会支持Unicode字符,而不仅仅是ASCII字符。具体地,此标志下,会使用Character.toUpperCase/toLowerCase来转换大小写。
x 对应于Pattern.COMMENTS标志:忽略空白字符(即\s代表的字符),忽略#和行结束符之前的内容(同时也忽略行结束符)。
m 对应于Pattern.MULTILINE标志:使得^和$可以匹配文本中间的行结束符之前和之后的位置。具体见^$
s 对应于Pattern.DOTALL标志:点号.可以匹配行结束符

局部模式修饰符:(?modifier:…),如(?i:…)

要限制模式修饰符的作用范围,除了将之放于括号内部,也可以简单地使用(?x:…)形式。比如<B>(?:(?i)text)</B>可以简化成<B>(?i:text)</B>。需要注意的是,虽然与括号形式类似,但它并不是捕获组,无法捕获内容。

文本范围: \Q…\E

\Q…\E会把其内部的字符当作普通文本来对待,而不是视为正则表达式。特别需要注意的是内部文本不能包含\E,可以使用\Q…\E\\E\Q…\E来代替。

1
2
3
4
// match: \s <--- \Q\s\E
assertEquals(true"\\s\\t".matches("\\Q\\s\\t\\E"));
// match: \E <--- \Q\s\E\\E\Q\t\E
assertEquals(true"\\s\\E\\t".matches("\\Q\\s\\E\\\\E\\Q\\t\\E"));

分组和捕获

捕获/分组括号:(…)和\1、\2、…

普通的没有特殊含义的括号通用用于分组捕获,形式为(...)

对于捕获的分组,可以使用反向引用来获取子表达式匹配的文本。Java使用\1、\2、…形式的反向引用,后面的数字表示分组的编号。分组编号是按照左括号(出现的次序来分配的。在Java中,分组编号的数目是没有限制的。

1
2
3
4
5
6
// 【样例1】捕获分组1:abc
assertEquals(true"abc1abc".matches("(\\w+)1\\1"));
// 【样例2】捕获分组1:a,分组2:b,分组3:c
assertEquals(true"abc1cba".matches("(\\w)(\\w)(\\w)1\\3\\2\\1"));
// 【样例3】一个很奇怪的例子,这与Java在匹配分组循环时回溯逻辑有关,具体原因不便讨论。
assertEquals(true"abc11".matches("(\\w)+1\\1"));

 

仅分组不捕获的括号:(?:…)

(?:…)仅用于分组,但不能用来提取文本。

固化分组:(?>…)

固化意思是说,一旦括号内的子表达式匹配成功之后,匹配的内容就被固化,在接下来的匹配过程中是不变的,除非整个子表达式被弃用。

1
2
3
assertEquals(true"1abcde2".matches("1.*2"));
// .*匹配到abcde2之后,将会被固化,但是之后的2无法匹配成功,需要强迫.*释放最后匹配的内容(即e),但是由于是固化分组,这个操作无法实现。
assertEquals(false"1abcde2".matches("1(?>.*)2"));

多选分支:…|…|…

多选分支可以用来在同一个位置测试多个子表达式。Java会按照从左到右的次序来匹配。子表达式可以为空表达式,比如(?:abc|)等价于(?:abc)?。

量词

匹配优先量词:*、+、?、{num,num}

两次可以限制作用对象的匹配次数*表示匹配次数零次或多次,+表示匹配次数一次或多次,?表示匹配次数零次或一次,{cmin,cmax}表示匹配次数为cmin到cmax次(均包含边界)。

需要注意,X{0,0}的意思不是“不出现X”,而是不进行任何匹配,也即跟没有是一样的。如果要实现“不出现X”,请使用否定环视功能。

忽略优先量词:*?、+?、??、{num,num}?

默认情况下,量词是匹配优先的,也即匹配尽可能多的内容。而忽略优先则相反,会匹配尽可能少的内容。

占有优先量词:*+、++、?+、{num,num}+

占有优先与固化分组类似,一旦匹配某些内容,将不会交还这些内容,除非整个子表达式被弃用。往往可以使用占有量词来优化正则表达式。

1
1
分享到:
评论

相关推荐

    正则表达式实用手册

    2. **正则表达式进阶** - **选择与或**:使用 `|` 符号实现多个模式的或操作,如 `abc|def` 可匹配 "abc" 或 "def"。 - **否定预查**:使用 `(?!...)` 表示后面不能跟指定的模式,如 `\d+(?!\d)` 匹配连续的数字但...

    正则表达式.rar

    这个压缩包文件"正则表达式.rar"包含了一个名为"正则表达式.chm"的帮助文档,很可能是关于Java中正则表达式的详细教程或参考手册。 正则表达式的基本概念: 1. **模式(Pattern)**:正则表达式就是一种模式,它...

    java正则表达式(ppt文档).ppt

    ### Java正则表达式概述 #### 一、正则表达式简介 正则表达式是一种强大的文本处理工具,能够提供灵活而高效的模式匹配方法。它主要用于处理文本数据,包括查找特定字符模式、提取、编辑、替换或删除文本子字符串...

    Java正则表达式笔记.pdf

    Java正则表达式是编程语言Java中用于处理文本的强大工具,它允许开发人员根据特定模式匹配、搜索和替换文本。在Java 2中引入的`java.util.regex`包提供了全面的支持,使得正则表达式的使用变得更为便捷。本文将探讨...

    正则表达式的应用

    - **教程**:MDN Web文档、W3School等网站提供了详细的正则表达式教程。 5. **编程语言支持** - **Python**:使用`re`模块,提供了丰富的函数进行匹配、搜索、替换等操作。 - **JavaScript**:全局对象`RegExp`...

    正则表达式的api

    4. 正则表达式进阶: - **非贪婪匹配**:通过在量词后添加`?`,使匹配尽可能少的字符,如`.*?`。 - **否定预查**:`(?!)`表示后面不能跟指定的模式,如`a(?!b)`匹配不紧跟'b'的'a'。 - **条件表达式**:在某些...

    正则表达式入门.doc

    10. **函数与方法**:在不同编程语言中,如JavaScript、Python、Java,使用正则表达式的方式略有不同,但通常都有`match`、`search`、`replace`、`split`等方法,用于执行查找、替换和拆分字符串的操作。 11. **...

    js正则表达式资料

    还有各种教程和文档,如“正则表达式系统教程”、“Java正则表达式使用详解”等,可以帮助理解不同场景下的应用。 以上内容涵盖了JavaScript正则表达式的基础和进阶知识点,对于理解和使用JavaScript正则表达式进行...

    java常用正则表达式

    四、正则表达式进阶 1. 分组与引用:`( )` 可以创建分组,`\1`、`\2` 等引用前面的分组。 2. 选择符:`|` 表示或关系,如 `/apple|banana/` 匹配 'apple' 或 'banana'。 3. 非贪婪匹配:在量词后加 `?` 可使匹配尽...

    编译原理--正则表达式文档

    7. **正则表达式进阶** - **环视条件**: `(?=pattern)` 和 `(?!pattern)` 分别表示前瞻和后瞻,确保匹配前后满足特定条件。 - **非贪婪匹配**: 添加 `?` 使其变为非贪婪模式,例如 `.*?` 会尽可能少地匹配字符。 ...

    精通正则表达式-第三版-简体中文版

    2. **Java**:从Java 1.4开始引入java.util.regex包,支持正则表达式,Java 1.5和1.6增加了更多特性。 3. **PHP**:PHP在后来的版本中增加了内置的正则表达式支持,提供了preg_match系列函数。 4. **JavaScript**...

    常用正则表达式包含C#javaVBscriptJscript等

    了解各种编程语言中的正则表达式API,结合实际需求编写高效、准确的正则表达式,是每个IT从业者必备的技能之一。通过学习和实践,你可以编写出更复杂、功能更强大的正则表达式,解决各种输入验证问题。

    总结常用正则表达式(java,js)

    下面将详细讲解正则表达式的常见模式和使用方法,以及如何在Java和JavaScript中应用它们。 1. **基础概念** - **元字符**: 特殊含义的字符,如`.`代表任意字符,`^`表示行首,`$`表示行尾,`\`用于转义。 - **...

    正则学习资料

    实例教程是学习正则表达式的好方法,因为它们可以帮助我们直观理解各种模式的工作原理。在实例教程中,你可以找到各种常见和复杂的正则表达式示例,如匹配邮箱地址、电话号码、日期格式等。通过实际操作,学习如何...

    JAVA开发实战经典

    3. 正则表达式进阶: - 分组:使用括号可以将正则表达式分组,允许捕获和引用子匹配。 - 非捕获组:`(?:...)`可以创建一个非捕获组,不被当作独立的匹配项。 - 选择器:`(option1|option2)`表示option1或option2...

    最新Java2实用教程电子教程

    7. **Java API**:教程会介绍标准Java库中的一些关键类和接口,如日期时间API、正则表达式、网络编程(Socket和ServerSocket)、反射机制等。 通过学习这个Java2实用教程电子教程,读者不仅可以掌握Java编程的基本...

    Java基础案例教程(第2版)-课后习题答案.zip

    习题可能会涵盖字符串的创建、比较、截取、拼接以及使用正则表达式进行匹配和替换。 5. **异常处理**:学习如何使用try-catch-finally语句块来捕获和处理程序运行时可能出现的错误。 6. **集合框架**:Java集合...

    Java进阶教程之String类

    此外,String类还支持其他方法,如split()用于分割字符串,matches()用于验证字符串是否匹配正则表达式,以及concat()用于连接两个字符串等。 在编程实践中,理解和熟练运用String类的各种方法可以提高代码的效率和...

    java.rar黑马java基础笔记

    这份笔记由多个部分组成,分别详细讲解了Java的基础语法、集合、多线程、IO以及反射和正则表达式等关键概念。 1. **基础语法**: - **变量与数据类型**:包括基本数据类型(如int、char、boolean)以及引用数据...

Global site tag (gtag.js) - Google Analytics