项目小版本上线偷得半日闲,刚刚又重新看了一遍正则,这次有空仔细看,完全理解了一遍,收获很大,下面整理一下
- 总体
- 正则其实非常简单,没有太多东西,就只有几个组成部分:表示字符/表示数量/表示位置/其他
- 不过确实正则可读性非常差,我觉得首要原因就是组成成分混乱,所以我的技巧是分两步,第一步是断句,第二步是理解,断句非常重要
- 表示字符
- 普通字符
- 任意字符(元字符需要转义)(空格也是直接匹配)
- 元字符(匹配一类字符)
- . -匹配除换行符以外的任意字符
- \w -匹配字母或数字或下划线或汉字(word)
- \s -匹配任意的空白符(skip)
- \d -匹配数字(digit)
- 表达式
- [-]反括号能匹配里边的元素,能通过-表示一个范围
- 举例
- [aeiou]就匹配任何一个英文元音字母
- [.?!]匹配标点符号(.或?或!)
- [0-9]代表的含意与\d就是完全一致的:一位数字
- [a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)
- 普通字符
- 表示数量(限定符)
- 元字符
- * -重复零次或更多次
- + -重复一次或更多次
- ? -重复零次或一次
- 表达式
- {n} -重复n次
- {n,} -重复n次或更多次
- {n,m} -重复n到m次
- 贪婪/懒惰
- 看着高大上但是很简单的概念,用起来也非常简单,就一个字符
- 在限定符后边加一个?就意味着从贪婪匹配变成了懒惰匹配
- 当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符
- 以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串
- 如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配
- 有时我们更需要懒惰匹配,也就是匹配尽可能少的字符
- 比如 .*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
- 元字符
- 表示位置
- 都是元字符,没几个
- \b -匹配单词的开头或结尾,它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)\w (begin)
- ^ -匹配字符串的开始
- $ -匹配字符串的结束
- 零宽断言
- 它跟表示位置有点类似的地方,有人直接认为它就是表示位置的一种方法,但我不这么认为,我认为它不一样的原因是它可以截取字符串
- 它本身还有一个特殊属性是,它不会占有匹配位,也就是它不会匹配掉字符,而前面的匹配字符和匹配位置都是会匹配掉字符的(结合表示位置的元字符理解更佳)
- 表达式
- (?=exp) -匹配exp前面的位置
- 断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分)
- (?<=exp) -匹配exp后面的位置
- 断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分)
- (?!exp) -匹配后面跟的不是exp的位置
- 断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字
- (?<!exp) -匹配前面不是exp的位置
- 断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字
- (?=exp) -匹配exp前面的位置
- 其他
- 元字符和转义字符
- 这块我觉得正则做得不太好,<有意义,但是却不是转义字符,只能通过前后文判断它属于什么情况下,还有空格的表示,虽然不会有语法错误,但都降低了表达式的可读性
- 转义字符是反斜杠,它其实有二元的作用,普通字符加反斜杠会成元字符,本身就是元字符的特殊字符加反斜杠表示它本身(表示为普通字符身份)
- 这里提三个关于字符的概念:元字符/普通字符/特殊字符
- 所有字符分为普通字符(所有大小写英文字母)、特殊字符(符号类的)、数字 和 其他字符(中文/日文什么鬼的根本不管的字符)
- 而元字符是从普通字符和特殊字符中挑选出来的字符,特殊字符成为元字符形式上不会有变化,普通字符成为元字符形式上需要加一个反斜杠
- 所有元字符统计
- (、)、|、. 、*、+、?、^、$、\、{、}、/、
- 不是元字符的统计
- 短横线、减号、<、>、
- 反义字符
- 这是一整套东西,一整套简单的东西,而且在命令上有规律
- 用它的目的是想查找除了数字以外,其它任意字符都行的情况
- 默认命令的话就是小写改大写,非默认命令是加^,如下
- \W -匹配任意不是字母,数字,下划线,汉字的字符
- \S -匹配任意不是空白符的字符
- \D -匹配任意非数字的字符
- \B -匹配不是单词开头或结束的位置
- [^x] -匹配除了x以外的任意字符
- [^aeiou] -匹配除了aeiou这几个字母以外的任意字符
- 分组
- 正则里是使用小括号进行分组的,这里的分组有两个作用
- 第一个跟其他地方使用小括号分组是一样的,都是表示运算的优先级,可以把括号内的内容当成一个优先级更高的整体
- 第二个是 后向引用
- 默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2
- 而后边的表达式中可以通过组号引用前面的组内容,比如\1 代表分组1匹配的文本
- 也可以自己指定子表达式的组名:(?<Word>\w+)(或者把尖括号换成‘也行:(?‘Word‘\w+)),这样就把\w+的组名指定为Word了,引用这个分组捕获的内容:\k<Word>
- 另外(?:exp)匹配exp,不捕获匹配的文本,只是为了不给此分组分配组号
- 正则里是使用小括号进行分组的,这里的分组有两个作用
- 分支条件
- 正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配
- 具体方法是用|把不同的规则分隔开
- 分支符号运算顺序最低,但是可以使用小括号来灵活调整范围
- 注释
- 通过语法(?#comment)来包含注释
- 元字符和转义字符
参考文献:
http://deerchao.net/tutorials/regex/regex.htm
时间: 2024-10-18 12:34:56