正则表达式是由普通字符(例如字符a ~ z)及特殊字符(称为元字符)组成的匹配模式字符串。
普通字符 非打印字符 特殊字符 次数限定符 贪婪与非贪婪限定符 定位符 选择与分组 向后引用
|
|
普通字符 |
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。 |
A | -> | A | c | -> | abcde | bcd | -> | abcde |
|
|
非打印字符 |
除以上的普通字符外,还有少量的非打印字符,非打印字符使用转义符号 "\" 表示。如下表: |
字符 | 说明 | 等同 | \cx | 匹配由x指明的控件字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A~Z或a~z之一,否则,将c视为一个原义的'c'字符。 | | \f | 匹配一个换页符 | \x0c和\cL | \n | 匹配一个换行符 | \x0a和\cJ | \r | 匹配一个回车符 | \x0d和\cM | \t | 匹配一个制表符 | \x09和\cI | \v | 匹配一个垂直制表符 | \x0b和\cK | \s | 匹配任何空白字符,包括空格、制表符、换页符等 | [\f\n\r\t\v] | \S | 匹配任何非空白字符 | [^\f\n\r\v] |
|
|
特殊字符 |
一些有特殊含义的字符,通常都是正则表达式语法中规定的匹配字符。如下表: |
类型 | 字符 | 说明 | 首尾 | ^ | 匹配输入字符串的 开始位置。除非在广括号表达式中使用,此时它表示不接受该字符集合 | | $ | 匹配输入字符串的 结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配'\n'或'\r' | 次数 | * | 匹配前面的子表达式 零次 或 多次 | | ? | 匹配前面的子表达式 零次 或 一次,或指明一个非贪婪限定符 | | + | 匹配前面的子表达式 一次 或 多次 | - | . | 匹配除换行符 \n 之外的任何单字符 | 括号 | () | 标记一个子表达式的开始和结束位置。子表达式可以获取供后续使用 | | [] | 标记一个中括号表达式的开始 | | {} | 标记限定符表达式的开始 | 字符 | \d | 任意一个数字,0~9中的任意一个 | | \w | 任意一个字母、数字或下画线,也就是 A ~ Z、a ~ z、0 ~ 9、_中任意一个 | | \D | 匹配所有的非数字字符 | | \W | 匹配所有的字母、数字、下画线以外的字符 | - | \ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如 'n' 匹配字符 'n','\n'匹配换行符。 | - | | | 指明两项之前的一个选择 |
|
示例如: |
\$d | -> | abc$de | | Tom|Jack | -> | I'm Tom, he is Jack | | (go\s*)+ | -> | Let's go go go! | | ¥(\d+\.?\d*) | -> | $10.9, ¥20.5 | 单独获取括号范围匹配到的内容是:20.5 | \d\d | -> | abc123 | | a.\d | -> | aaa100 | | [bcd][bcd] | -> | abc123 | | [^abc] | -> | abc123 | |
|
|
次数限定符 |
次数限定符即限定匹配某一字符表达式的次数,用来指定正则表达式的一个给定组合必须要出现多少次才能满足匹配。 |
字符 | 说明 | 举例 | * | 匹配前面的子表达式零次或多次 | zo* 能匹配 z 及 zoo | + | 匹配前面的子表达式一次或多次 | zo+ 能匹配 zo 及 zoo | ? | 匹配前面的子表达式零次或一次 | do(es)? 能匹配 do 及 does | {n} | n是一个非负整数。匹配确定的n次 | o{2} 只能匹配 oo | {n,} | n是一个非负整数。至少匹配n次 | o{2,} 能匹配 oo 或 fooood中的多个o | {n,m} | m和n均为非负整数,其中n<=m。 最少匹配n次且最多匹配m次 | o{1,3} 能匹配 1个、2个或3个 o |
|
|
贪婪与非贪婪限定符 |
贪婪限定符会尽可能多的匹配文字,只有在它们的后面加个一个"?"就可以实现非贪婪或最小匹配 |
-
A* | 匹配 0 次或 n 次 | A+ | 匹配 1 次或 n 次 | A? | 匹配 0 或 1 次 | A{n} | 匹配 n 次 | A{n,} | 匹配 n 或 多次 |
A*? | 匹配 0 次或 n 次 | A+? | 匹配 1 次或 n 次 | A?? | 匹配 0 或 1 次 |
|
例如,你可能要搜索一个HTML文档来查询一处包含在H1标记中的章节标题。在文档中该文字可能具有如下形式: |
<H1> Chapter 1 - Introduction to Regular Expressions </H1> |
下面的表达式匹配从开始的小于号(<)到H1标记结束处的大于号之间的所有内容: |
<.*> |
如果所要匹配的就是开始的H1标记,则下述非贪婪地表达式就只能匹配到<H1>: |
<.*?> |
|
定位符 |
定位符用来描述匹配到的字符串或单词的边界。定义符可以将一个正则表达式固定在一行的开始和结束,也可以创建只在单词内或只在单词的开始或结尾处出现的正则表达式。 |
字符 | 说明 | ^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,"^"也匹配'\n'或'\r'之后的位置 | $ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,"$"也匹配'\n'或'\r'之后的位置 | \b | 匹配一个单词边界,也就是指单词和空格间的位置 | \B | 匹配非单词边界 |
|
示例如下: |
^aaa | -> | xxx aaa xxx | aaa xxx xxx | aaa$ | -> | xxx aaa xxx | xxx xxx aaa | .\b. | -> | @@@abc | | \bend\b | -> | weekend,endfor,end | |
|
|
替换与分组 |
替换使用 | 字符来允许在两个或多个替换选项之间进行选择。例如,可以扩展章节标题正则表达式,以返回比章标题范围更广的匹配项。但是,这并不象您可能认为的那样简单。替换匹配 | 字符任一侧最大的表达式。 您可能认为,下面的表达式匹配出现在行首和行尾、后面跟一个或两个数字的 Chapter 或 Section: |
^Chapter|Section [1-9][0-9]{0,1}$ |
很遗憾,上面的正则表达式要么匹配行首的单词 Chapter,要么匹配行尾的单词 Section 及跟在其后的任何数字。如果输入字符串是 Chapter 22,那么上面的表达式只匹配单词 Chapter。如果输入字符串是 Section 22,那么该表达式匹配 Section 22。通过在上面的正则表达式的适当位置添加括号,就可以使该正则表达式匹配 Chapter 1 或 Section 3: |
^(Chapter|Section) [1-9][0-9]{0,1}$ |
使用圆括号同时会有一个副作用,就是相关的匹配会被缓存。为了消除缓存,此时可以将"?:"放在第一个选项前,用来消除这种副作用。其中"?:"是非捕获元之一,还有两非捕获元是 "?=" 和 "?!", 这两个还有更多的含义:
- 前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串;
- 后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
可以在正则表达式模式圆括号内部的前面使用"?:"来防止存储该匹配供后续使用。对上面所示正则表达式的下述修改提供了免除子匹配存储的相同功能: |
^(?:Chapter|Section) [1-9][0-9]{0,1}$ |