您当前的位置: 首页 >  正则表达式

liaowenxiong

暂无认证

  • 3浏览

    0关注

    1171博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

正则表达式详解

liaowenxiong 发布时间:2020-08-09 15:05:29 ,浏览量:3

文章目录
  • 一、表示数量的元字符
  • 二、表示字符的元字符
    • 字符集
    • 取反字符集合
    • 字符范围
    • 单词边界表达式
    • 控制符
    • 其它代表字符的元字符
    • POSIX 字符集
  • 三、修饰符
  • 四、环视/预查/零宽断言
    • (一)顺序肯定环视
    • (二)顺序否定环视
    • (三)逆序肯定环视
    • (四)逆序否定环视
  • 五、非捕获性分组
  • 六、替换变量
  • 七、转义符号
  • 八、表示位置的元字符
  • 九、特别说明
    • 匹配字符失败会尝试匹配位置
    • 匹配单词边界位置

一、表示数量的元字符

表示数量的元字符,也叫“限定符”,也叫“量词”。假设匹配个数为 x,那么下面不同的量词的匹配个数可以通过数学表达式列出。

元字符匹配个数(用 x 表示)意义*x ≥ 0表示任意数量(包括 0);表示任意个;表示匹配其前面的字符任意个数;表示匹配任意个其前面的字符或者子表达式所代指的字符;表示前面的子表达式出现任意次数(包括 0 次)将会被匹配到;表示之前的字符连续出现任意次数(包括 0 次)将会被匹配到。 [abc]* 表示匹配 ≥0 个 由中括号所包含(指定)的(任意)字符所组成的字符串;例如,e*f 表示 f 前面的 e 出现任意次将会被匹配;zo* 能匹配 zzo zoo 等。其实就是代表一个大于等于 0 的数量集,所以 * 等价于 {0,}。(匹配优先)+x ≥ 1表示 1 个或多个;匹配前面的子表达式(代指的字符)一次或多次;表示匹配前面的字符 1 个或者多个;表示匹配其前面的字符至少 1 次,也就是前面的字符必须有至少一个。例如,zo+ 能匹配 zozoo 等,但不能匹配 z。比如 abc+ 表示 ab 后面 c 至少要出现 1 次才会被匹配到。其实就是代表一个大于等于 1 的数量集,所以 + 等价于 {1,}。(匹配优先)?x = 0 or x = 1表示 0 个或 1 个;匹配前面的子表达式零次或一次,也就是前面的子表达式可有可无。例如,do(es)?可以匹配 dodoes。其实 ? 等价于{0,1}。(匹配优先){n,m}n ≤ x ≤ m表示 n 个到 m 个,nm 均为非负整数,其中 n ≤ m。最少匹配前面的字符 n 次且最多匹配 m 次。例如,o{1,3} 会匹配 fooooood 中的前3 个 o 和后 3 o,完整的正则式成功匹配 1 次后,会继续匹配后面的字符,知道字符串末尾为止,所以会匹配出两个字符串。o{0,1} 等价于 o?。(匹配优先){n,}x ≥ n表示 n 个到无限个,表示匹配前面的字符至少 n 个。n 是一个非负整数,即最少 n 个,其实就是一个大于等于 n 的整数集。例如,o{2,} 表示匹配至少 2 个字符 o,所以不能匹配 Bob 中的 o,但能匹配 foooood 中的所有 oo{1,} 等价于 o+o{0,} 则等价于 o*。(匹配优先){,m}0 ≤ x ≤ m表示 0 个到 m 个,即最多 m 个(匹配优先){n}x = n表示 n 个,n 是非负整数,表示前面的子表达式必须出现 n 次;表示前面的字符连续出现 n 次,将会被匹配到。比如 a{2} 表示 a 连续出现两次就会被匹到,即匹配 aa{n,m}?n ≤ x ≤ m表示 n 个到 m 个(忽略优先)*?x ≥ 0表示任意数量(忽略优先)+?x ≥ 1表示 1 个或多个(忽略优先)??x = 0 or x = 1表示 0 个或 1 个(忽略优先)

注:“匹配优先”表示在整个正则式匹配成功的前提下,尽可能匹配更多的字符;“忽略优先”表示在整个正则表达式可以匹配成功的前提下,匹配的字符数越少越好,具体可以参见《正则表达式的贪婪模式、非贪婪模式、占有模式》。

二、表示字符的元字符 字符集

又叫字符组,[] 表示指定范围内的任意单个字符,用来匹配所包含字符中的任意一个字符或者所限定范围内的字符中的任意一个字符。

集合表达式说明[abc]匹配方括号中的任意一个字符;匹配 ab,c 中的任意一个,例如,[abc] 可以匹配 plain 中的 a

特别注意:

  1. 如果中括号中包含元字符,则元字符降级为普通字符,不再具有元字符的功能,例如, [+.?] 匹配加号或者点号或者问号;
  2. 例如,[\d] 这不是匹配任意一个数字,而是只匹配字符 d\d 本是一个元字符,放在 [] 内就会变成普通字符 d,如果写成 \\d,则表示匹配 \d,换句话说如果要使用 \d 元字符的含义,不能放在方括号 [] 中;
  3. 例如,[\w] 不是匹配英文字母、阿拉伯数字、下划线中的任意一个字符,仅匹配 \ 或字符 w,居然和 [\d] 的效果不同,醉了
取反字符集合

又叫排除性字符组,[^] 表示匹配未被方括号包含的任意一个字符。^ 这个字符放在方括号内表示非、取反的意思;^ 放在外面则表示被匹配的字符串的头部,可以看『表示位置的元字符』小节。

集合表达式说明[^abc]表示匹配除方括号内字符以外的任意一个字符,[^abc] 可以匹配“plain”中的plin 字符范围

方括号 [] 表达式,意为匹配括号中所限定的字符集中的任意一个字符。 [n-m] 匹配指定范围内的任意一个字符,- 表示字符范围。 [^n-m] 取反字符范围。匹配不在指定范围内的任意一个字符。

表达式说明[a-z]表示任意一个小写英文字母;匹配 az 范围内的小写英文字母中任意一个字符[^a-z]匹配不在 az 范围内的任意一个字符;匹配除了 a 到 z 范围的小写英文字母以外的任意一个字符;匹配除了小写英文字母以外的任意一个字符[a-z0-9]匹配小写英文字母和阿拉伯数字中的任意一个字符[0-9]匹配任意一个阿拉伯数字 单词边界表达式 表达式说明\b匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。\B匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er” 控制符 表达式说明\cx匹配由 x 指明的控制字符。例如,\cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Za-z 之一。否则,将 c 被视为一个普通字符\f匹配一个换页符。等价于 \x0c\cL\n匹配一个换行符。等价于 \x0a\cJ\r匹配一个回车符。等价于 \x0d\cM\s匹配任意一个空白字符。包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]\t匹配一个制表符。等价于 \x09\cI\v匹配一个垂直制表符。等价于 \x0b\cK 其它代表字符的元字符 表达式说明.匹配除 \n 之外的任意一个字符。要匹配包括 \n 在内的任何字符,可以使用模式 (.|\n),表示除了换行符以外的任意一个字符或者换行符,换言之就是匹配任意一个字符了\w\W匹配任意一个字符\d\D匹配任意一个字符\s\S匹配任意一个字符.*表示匹配出现任意次的任意单个字符(除了换行符),换句话说就是匹配任意长度的任意字符。例如,a.* 表示 a 字母后面存在任意长度的任意字符都可以被匹配到。.* 可以这样理解,* 是限定符,表示其所限定的元素(本例表达式的点符号 . 就是 * 所限定的元素)可以出现任意次(≥ 0)\a匹配任意一个英文字母,等同于 [a-zA-Z]\l匹配任意一个小写英文字母,等同于 [a-z]\L匹配除了小写英文字母以外的任意一个字符,等同于 [^a-z]\u匹配任意一个大写英文字母,等同于 [A-Z]\U匹配除了大写英文字母以外的任意一个字符,等同于 [^A-Z]\d匹配任意一个阿拉伯数字,等价于 [0-9]\D匹配除阿拉伯数字之外的任意一个字符,等同于 [^0-9]\S匹配非空白字符的任意一个字符。等价于 [^\f\n\r\t\v]\w匹配英文字母、阿拉伯数字、下划线中的任意一个字符,等同于 [0-9A-Za-z_]\W匹配英文字母、阿拉伯数字、下划线之外的任意一个字符,等同于 [^0-9A-Za-z_]\xn匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,\x41 匹配 A 。正则表达式中可以使用 ASCII 编码。\n标识一个八进制转义值或一个向后引用。如果 \n 前面存在 n 对应的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字(0-7),则 n 为一个八进制转义值。例如,(.)\1 匹配两个连续的相同字符。. 匹配任意一个字符(除了换行符),而 \1 则引用前面第 1 个小括号的内容,也就是引用 (.) ,所以 . 匹配什么,就引用什么,例如,. 匹配到字符 A,那么就要引用 A,合起来就是 AA\un匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如,\u00A9 匹配版权符号 ©x|y匹配 xy。例如,z|food 能匹配 zfood(z|f)ood 则匹配 zoodfood\x匹配任意一个十六进制数字,等同于 [0-9A-Fa-f]\X匹配除了十六进制数字以外的任意一个字符,等同于 [^0-9A-Fa-f] POSIX 字符集 表达式说明[[:alpha:]]Alphabetic characters: [:lower:] and [:upper:] 表示匹配任意一个英文字母(不区分大小写)。等价于 \a。比如 a[[:alpha:]]{3} 表示只有 a 字母后面跟随任意 3 个英文字母的字符串才会被匹配到。[[:lower:]]Lower-case letters 表示匹配任意一个小写英文字母。等价于 \l。比如 a[[:lower:]]{3} 表示只有当 a 后面跟着任意 3 个小写英文字母时,才会被匹配到。[[:alnum:]]Alphanumeric characters: [:alpha:] and [:digit:] 表示匹配任意一个数字或英文字母。等价于 [a-zA-Z0-9]。比如 a[[:alnum:]]{3} 表示当 a 后面的 3 个字符为数字或字母时会被匹配到。[[:upper:]]Upper-case letters. 表示匹配任意一个大写英文字母。比如 a[[:upper:]]{3} 表示只有当 a 后面的 3 个字符均为大写英文字母时,才会被匹配到[[:digit:]]表示匹配任意一个数字。等价于 \d。比如 a[[:digit:]]{3} 表示只有当 a 后面的 3 个字符均为数字时,才会被匹配到。[[:space:]]Space characters: tab, newline, vertical tab, form feed, carriage return, and space.表示匹配任意一个空白字符,即匹配制表符、换行符、垂直制表符、换页符、回车符和空格中的任意一个字符[[:blank:]]Blank characters: space and tab.表示匹配空格或制表符[[:cntrl:]]Control characters. In ASCII, these characters have octal codes 000 through 037, and 177 (‘DEL’). In other character sets, these are the equivalent characters, if any. 代表键盘上面的控制按键。匹配任意一个控制字符。在 ASCII 中,这些字符有八进制代码 000 到 037 和 177(‘DEL’)。在其他字符集中,这些字符是等价的字符(如果有的话)。[[:graph:]]Graphical characters: [:alnum:] and [:punct:]. 除了空白字符(空白键和 Tab 键)以外的其它所有按键,也就是匹配任意一个图形字符;英文字母、数字、标点符号中的任意一个字符[[:print:]]Printable characters: [:alnum:], [:punct:], and space. 匹配任意一个可打印字符,即数字、英文字母、标点符号、空格字符中的任意一个字符[[:punct:]]Punctuation characters: ! " # $ % & ’ ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` ~ 表示匹配任意一个标点符号[[:xdigit:]]Hexadecimal digits. 匹配任意一个十六进制数字

我们可以把 [[:alpha:]] 拆成两部分理解: 第一部分:最外层的 [ ],表示指定范围内的任意单个字符; 第二部分:最内层的 [:alpha:],表示不区分大小写的字母。

注:Java、PHP 等开发语言支持 POSIX 字符集,JS 不支持。

三、修饰符

javaScript 中正则表达式的修饰符:

修饰符说明g全文查找i忽略大小写查找m多行查找 四、环视/预查/零宽断言

“环视”已经是够奇葩的叫法,又 TMD 的叫“零宽断言”,又叫“预查”。

由于匹配是零宽度的,故最终匹配到的只是一个位置。

环视按照方向划分,有顺序和逆序两种(也叫前瞻和后瞻),按照是否匹配有肯定和否定两种,组合起来便有 4 种环视。

顺序、前瞻就是向前,向左边查找;逆序、后瞻就是向后,向右边查找。

总结:所谓环视,就是根据 pattern,也就是子表达式匹配到一个位置,然后根据前后方向匹配另外一个子表达式而已。

对于这些逆天的名称我真的是醉了,摆明了得到阿里系的真传!!!😂

表达式说明(?=pattern)正向肯定预查,又叫“顺序肯定环视”,又叫“前瞻肯定环视”,在任何匹配 pattern 的字符串开始处正向(往左边方向,向前面)匹配查找字符串,这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,Windows(?=95|98|NT|2000) 能匹配 Windows2000 中的Windows,但不能匹配 Windows3.1 中的 Windows。预查不消耗字符(?!pattern)正向否定预查,又叫“顺序否定环视”,又叫“前瞻否定环视”,在任何不匹配 pattern 的字符串开始处正向匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,Windows(?!95|98|NT|2000) 能匹配 Windows3.1 中的 Windows,但不能匹配 Windows2000 中的 Windows。预查不消耗字符(?反向否定预查,又叫“逆序否定环视”,在任何不匹配 pattern 的字符串结尾处反向(往右边方向,向后面)匹配查找字符串。例如,(? 能匹配 3.1Windows 中的 Windows,但不能匹配 2000Windows 中的 Windows

目前 javaScript 只支持“顺序肯定环视”和“顺序否定环视”,我们就使用 js 演示下这两种环视的具体用法,另外两种环视我使用 python 为大家演示下。

(一)顺序肯定环视
var str = "123abc789",s;
//没有使用环视,abc直接被替换
s = str.replace(/abc/,456);
console.log(s); //123456789

//使用了顺序肯定环视,匹配到了后面跟着 abc的3,把3替换成3456
s = str.replace(/3(?=abc)/,3456);
console.log(s); //123456abc789

以上的 js 代码,使用了顺序肯定环视,先在 123abc789 中匹配 abc,然后根据方向确定真正需要匹配出来的字符串的开始查找的位置,方向是顺序,也就是向前,那么就从 abc 头部开始向前查找 3,找到后替换为 3456,所以替换后的结果是:123456abc789

其实正则式3(?=abc) 可以这样来理解,要查找后面跟着 abc3,要匹配(捕获)3 ,但是这个 3 后面必须跟着 abc

(二)顺序否定环视
var str = "123abc789",s;
// 使用了顺序否定环视,由于3后面跟着abc,不满意条件,故匹配失败,所以原字符串没有被替换
s = str.replace(/3(?!abc)/,3456);
console.log(s); //123abc789

正则式 3(?!abc) 可以这样理解,查找后面没有跟着 abc3,要匹配(捕获)3,但是这个 3 后面不能跟着 abc

(三)逆序肯定环视
import re
data = "123abc789"
# 使用了逆序肯定环视,替换左边为123的连续的小写英文字母,匹配成功,故abc被替换为456
regExp = r"(?            
关注
打赏
1661566967
查看更多评论
0.0718s