一、正则表达式作用
- 测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证
- 替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字
- 根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字
二、正则表达式创建方法——JavaScript
1、RegExp构造函数方法
var re = new RegExp(); //RegExp是一个对象,和Aarray一样 //但这样没有任何效果,需要将正则表达式的内容作为字符串传递进去 re =new RegExp("a"); //最简单的正则表达式,将匹配字母a re=new RegExp("a","i"); //第二个参数,表示匹配时不分大小写
注: RegExp构造函数第一个参数为正则表达式的文本内容,而第一个参数则为可选项标志.标志可以组合使用
- g (全文查找)
- i (忽略大小写)
- m (多行查找)
2、字面量方法 var re = new RegExp("a","gi"); //匹配所有的a或A
三、正则表达式语法
字符 | 描述 |
---|---|
\ | 转义字符,在之前,我们在字符串也用过这字符,即一些字符具有特殊含义,对其进行转义使它成为普通字符,而用在普通字符上又表示其有特殊含义 |
^ | 匹配输入字符串的开始位置,如果设置了匹配多行(m),那么也匹配行的开头 |
$ | 匹配输入字符串的结束位置。如果设置了匹配多行(m),那么也匹配行的结束 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。 |
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 |
(pattern) | 匹配pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 |
(?=pattern) | 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 负向预查,在任何不匹配pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 |
x|y | 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [?\f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^?\f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 |
\W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, '\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。. |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若? n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
\un | 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 |
预定义集合员字符类
代码 | 等同于 | 匹配 |
---|---|---|
. | IE下[^\n],其它[^\n\r] | 匹配除换行符之外的任何一个字符 |
\d | [0-9] | 匹配数字 |
\D | [^0-9] | 匹配非数字字符 |
\s | [ \n\r\t\f\x0B] | 匹配一个空白字符 |
\S | [^ \n\r\t\f\x0B] | 匹配一个非空白字符 |
\w | [a-zA-Z0-9_] | 匹配字母数字和下划线 |
\W | [^a-zA-Z0-9_] | 匹配除字母数字下划线之外的字符 |
简单量词+边界
代码 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 |
( ) | 将多个元字符或者原义文本字符用括号括起来形成一个分组,例如,^(13)[4-9]\d{8}$ 表示任意以 13 开头的移动手机号码 |
{n} | n 是一个非负整数。匹配 n 个元字符。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。匹配至少 n 个元字符。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。匹配 n 到 m 个元字符。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 |
\b | 匹配单词边界,代表单词的开始或者结尾,如“ 123a 345b 456 789d ”作为示例字符串,如果正则表达式是“ \b\d{3}\b ”,则仅能匹配 456 。 |
\B | 非单词边界 |
^ | 开头,字符串必须以指定的字符开始 |
$ | 结尾,字符串必须以指定的字符结束 |
| | 来表示或的关系,例如 [z|j|q] 表示匹配 z 、 j 、 q 之中的任意一个字母。 |
//实现首字母大写! var a = "ruby"; String.prototype.capitalize = function () { return this.replace(/^\w/, function (s) { return s.toUpperCase(); }); } alert(a.capitalize()) //Ruby //单词边界举例。要匹配的东西的前端或未端不能为英文字母阿拉伯字数字或下横线。 var str = "12w-eefd&efrew"; alert(str.match(/\b\w+\b/g)) //12w,eefd,efrew
特殊字符
字符 | 描述 |
---|---|
\n | 换行符 |
\r | 回车符 |
\t | 制表符 |
\f | 换页符(Tab) |
\cX | 与X对应的控制字符 |
\b | 退格符(BackSpace) |
\v | 垂直制表符 |
\0 | 空字符("") |
贪婪量词,惰性量词与支配性量词
贪婪量词,上面提到的所有简单量词 | 就像成语中说的巴蛇吞象那样,一口吞下整个字符串,发现吞不下(匹配不了),再从后面一点点吐出来(去掉最后一个字符,再看这时这个整个字符串是否匹配,不断这样重复直到长度为零) |
隋性量词,在简单量词后加问号 | 由于太懒了,先吃了前面第一个字符,如果不饱再捏起多添加一个(发现不匹配,就读下第二个,与最初的组成一个有两个字符串的字符串再尝试匹配,如果再不匹配,再吃一个组成拥有三个字符的字符串……)。其工作方式与贪婪量词相反。 |
支配性量词,在简单量词后加加号 | 上面两种都有个不断尝试的过程,而支配性量词却只尝试一次,不合口味就算了。就像一个出身高贵居支配地位的公主。但你也可以说它是最懒量词。由于javascript不支持,所以它连出场的机会也没有了。 |
var re1 = /.*bbb/g;//贪婪 var re2 = /.*?bbb/g;//惰性 // var re3 = /.*+bbb/g;//支配性,javascript不支持,IE与所有最新的标准浏览器都报错 alert(re1.test("abbbaabbbaaabbbb1234")+"");//true alert(re1.exec("abbbaabbbaaabbbb1234")+"");//null alert("abbbaabbbaaabbbb1234".match(re1)+"");//abbbaabbbaaabbbb alert(re2.test("abbbaabbbaaabbbb1234")+"");//true alert(re2.exec("abbbaabbbaaabbbb1234")+"");//aabbb alert("abbbaabbbaaabbbb1234".match(re2)+"");//abbb,aabbb,aaabbb
前瞻
继续在分组内做文章。前瞻与后瞻其实都属于零宽断言,但javascript不支持后瞻。
零宽断言 | ||
---|---|---|
正则 | 名称 | 描述 |
(?=exp) | 正向前瞻 | 匹配exp前面的位置 |
(?!exp) | 负向前瞻 | 匹配后面不是exp的位置 |
(?<=exp) | 正向后瞻 | 匹配exp后面的位置不支持 |
(?<!exp) | 负向后瞻 | 匹配前面不是exp的位置不支持 |
正向前瞻用来检查接下来的出现的是不是某个特定的字符集。而负向前瞻则是检查接下来的不应该出现的特定字符串集。零宽断言是不会被捕获的。
var str1 = "bedroom"; var str2 = "bedding"; var reBed = /(bed(?=room))///在我们捕获bed这个字符串时,抢先去看接下来的字符串是不是room alert(reBed.test(str1));//true alert(RegExp.$1)//bed alert(RegExp.$2 === "")//true alert(reBed.test(str2))//false var str1 = "bedroom"; var str2 = "bedding"; var reBed = /(bed(?!room))/ //要来它后面不能是room alert(reBed.test(str1))//false alert(reBed.test(str2))//true
//移除hr以外的所有标签,只留下innerText! var html = "<p><a href='http://www.cnblogs.com/rubylouvre/'>Ruby Louvre</a></p><hr/><p>by <em>司徒正美</em></p>"; var text = html.replace(/<(?!hr)(?:.|\s)*?>/ig,"") alert(text)
四、JavaScript和正则表达式相关的方法和属性
正则表达式对象的方法
- test,返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。如果存在则返回 true,否则就返回 false。
- exec,用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组。
- compile,把正则表达式编译为内部格式,从而执行得更快。
正则表达式对象的属性
- source,返回正则表达式模式的文本的复本。只读。
- lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的开始位置。
- $1...$9,返回九个在模式匹配期间找到的、最近保存的部分。只读。
- input ($_),返回执行规范表述查找的字符串。只读。
- lastMatch ($&),返回任何正则表达式搜索过程中的最后匹配的字符。只读。
- lastParen ($+),如果有的话,返回任何正则表达式查找过程中最后括的子匹配。只读。
- leftContext ($`),返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符。只读。
- rightContext ($'),返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符。只读。
String对象一些和正则表达式相关的方法
- match,找到一个或多个正则表达式的匹配。
- replace,替换与正则表达式匹配的子串。
- search,检索与正则表达式相匹配的值。
- split,把字符串分割为字符串数组。
五、表达式示例——正则表达式联机数据库:http://www.regexlib.com/
模式 | 说明 |
^\d{5}$ |
5 个数值数字,如美国邮政编码。 |
^(\d{5})|(\d{5}-\d{4}$ |
5 个数值数字或 5 个数字-短划线-4 个数字。匹配 5 位数字格式的美国邮政编码,或 5 位数字 + 4 位数字格式的美国邮政编码。 |
^(\d{5}(-\d{4})?$ |
与前一个相同,但更有效。使用 ? 可使模式中的 4 位数字成为可选部分,而不是要求分别比较不同的两个模式(通过另一种方式)。 |
^[+-]?\d+(\.\d+)?$ |
匹配任意有可选符号的实数。 |
^[+-]?\d*\.?\d*$ |
与上一个相同,但也匹配空字符串。 |
^(20|21|22|23|[01]\d)[0-5]\d$ |
匹配 24 小时制时间值。 |
/\*.*\*/ |
匹配 C 语言风格的注释 /* ... */ |
var osVersion = "-9---Ubuntu 8----9--"; //其中的8表示系统主版本号 |
取系统名称和版本号,模式为字母+空格,先整体匹配,再取分组的值 |
s.replace(/-+/g,'#'); |
将字符串中的连续的'-'替换成单个的'#' |
function trim(s) { |
去除字符串的前导空格与结尾空格 |