正则表达式


作者: 张敏;
标签: 正则表达式


正则表达式

前言

一说到正则表达式,估计很多人第一感觉就是难学看不懂。然后就跟我一样一再搁置,放着这个知识点不学。其实很多人感觉难学看不懂是因为正则表达式不像其他的代码易读性比较好,不能一眼看出代码的意思。用的不多的话不理解其语法的话就更加是闻正则色变。本篇将会介绍一些正则的基本用法,帮助更好的理解正则,我也趁此机会接触学习一下正则的基本语法。

知识点

什么是正则表达式?

正则表达式是一种描述字符串结构模式的形式化表达方法,这是《精通正则表达式》对于其的定义(估计很多人看了也不懂什么意思)。以我的理解来说,正则表达式就是定义一种规则去匹配符合该规则的字符。如果有用过通配符的话,可以将正则表达式跟通配符类比,它们都是用来进行文本匹配的工具。不过比起通配符,正则表达式可以更加精确地去匹配你所要匹配的文本,不过需要你编应相应的规则。

为什么要用正则表达式?

  • 复杂的字符串搜寻、替换工作,无法用简单的方式(类似借助标准库函数)达成。
  • 能够帮助你进行各种字符串验证。
  • 不止应用于编程语言中:JavaScript、JAVA、Perl、PHP、C#,也应用于许多操作系统的主流指令中:Linux/Unix、Mac、Windows PowerScript
  • 在Python爬虫应用中应用广泛

常用的正则匹配工具

  1. 在线匹配工具:
  2. 正则匹配软件
    • McTracer

正则字符的简单介绍

  1. 元字符介绍

    元字符 描述
    ^ ^会匹配行或者字符串的起始位置,有时还会匹配整个文档的起始位置
    $ $会匹配行或字符串的结尾
    \b 不会消耗任何字符只匹配一个位置,代表单词的开头和结尾。常用于匹配单词边界。例如你要查找hello这个单词。即为\bhello\b
    \d 匹配数字
    \w 匹配字母,数字,下划线或汉字
    \s 匹配空格。例如字符 "a b c" 正则:"\w\s\w\s\w" 一个字符后跟一个空格,如有字符间有多个空格直接把"\s" 写成 "\s+" 让空格重复
    . 匹配除了换行符以外的任何字符
    [abc] 字符组 匹配包含括号内元素的字符,这个比较简单了只匹配括号内存在的字符,还可以写成[a-z]匹配a至z的所以字母就等于可以用来控制只能输入英文
  1. 字符的转义
    如果想查找的是元字符本身的话,此时你应该使用\转义这些字符,取消这些字符的特殊意义。如果想使用.或*等特殊元字符。这些特殊字符的话可以在其前加个\。如.或*。如果要查找\本身也是如此,\。例如C:\document相当于匹配C:\document。
  2. 反义
    元字符的反义写法很简单,将原来的元字符改成大写就行了,意思与原来的相反
    • "\W" 匹配任意不是字母,数字,下划线 的字符
    • "\S" 匹配任意不是空白符的字符
    • "\D" 匹配任意非数字的字符
    • "\B" 匹配不是单词开头或结束的位置
    • "[^abc]" 匹配除了abc以外的任意字符
  3. 量词
    先解释关于量词所涉及到的重要的三个概念:
  • 贪婪(贪心)
如"*"字符,贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果失败则回退一个字符,然后再次尝试回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的
  • 懒惰(勉强)
如 "?" ,懒惰量词使用另一种方式匹配,它从目标的起始位置开始尝试匹配,每次检查一个字符,并寻找它要匹配的内容,如此循环直到字符结尾处。
  • 占有
如"+" 占有量词会覆盖事个目标字符串,然后尝试寻找匹配内容 ,但它只尝试一次,不会回溯
语法 描述
* (贪婪)重复零次或更多; 例如"aaaaaaaa" 匹配字符串中所有的a 正则: "a*" 会出到所有的字符"a"
+ (占有)重复一次或更多次; 例如"aaaaaaaa" 匹配字符串中所有的a 正则: "a+" 会取到字符中所有的a字符, "a+"与"a"不同在于"+"至少是一次而"" 可以是0次
? (懒惰)重复零次或一次; 例如"aaaaaaaa" 匹配字符串中的a 正则 : "a?" 只会匹配一次,也就是结果只是单个字符a
{n} 重复n次; 例如从"aaaaaaaa" 匹配字符串的a 并重复3次 正则: "a{3}" 结果就是取到3个a字符 "aaa";
{n,m} 重复n到m次; 例如正则 "a{3,4}" 将a重复匹配3次或者4次 所以供匹配的字符可以是三个"aaa"也可以是四个"aaaa" 正则都可以匹配到
{n,} 重复n次或更多次;
  1. 懒惰限定符
    • "*?" 重复任意次,但尽可能少重复

      如 "acbacb" 正则 "a.*?b" 只会取到第一个"acb" 原本可以全部取到但加了限定符后,只会匹配尽可能少的字符 ,而"acbacb"最少字符的结果就是"acb"

    • "+?" 重复1次或更多次,但尽可能少重复

      与上面一样,只是至少要重复1次

    • "??" 重复0次或1次,但尽可能少重复

      如 "aaacb" 正则 "a.??b" 只会取到最后的三个字符"acb"

    • "{n,m}?" 重复n到m次,但尽可能少重复

      如 "aaaaaaaa" 正则 "a{0,m}" 因为最少是0次所以取到结果为空

    • "{n,}?" 重复n次以上,但尽可能少重复

      如 "aaaaaaa" 正则 "a{1,}" 最少是1次所以取到结果为 "a"

正则进阶

  • 捕获分组

    使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。分组0对应整个正则表达式。

    后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。

    示例:

    \b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。

    你也可以自定义子表达式的组名。要指定一个子表达式的组名,语法如下:

    (?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。

    以下是捕获分组的常用的用法:

    语法 描述
    (exp) 匹配exp,并捕获文本到自动命名的组里
    (?<name>exp) 匹配exp,并捕获文本到名称为name的组里
    (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号

    以下为零宽断言用法:

    语法 描述
    (?=exp) 匹配exp前面的位置;如 "How are you doing" 正则"(?<txt>.+(?=ing))" 这里取ing前所有的字符,并定义了一个捕获分组名字为 "txt" 而"txt"这个组里的值为"How are you do";
    (?<=exp) 匹配exp后面的位置;如 "How are you doing" 正则"(?<txt>(?<=How).+)" 这里取"How"之后所有的字符,并定义了一个捕获分组名字为 "txt" 而"txt"这个组里的值为" are you doing"
    (?!exp) 匹配后面跟的不是exp的位置;如 "123abc" 正则 "\d{3}(?!\d)"匹配3位数字后非数字的结果
    (?<!exp) 匹配前面不是exp的位置;如 "abc123 " 正则 "(?<![0-9])123" 匹配"123"前面是非数字的结果也可写成"(?!<\d)123"
  • 分支条件
    正则表达式里的分枝条件指的是有几种匹配规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开

    例如:
    0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0753-6816488)。

应用场景

  • 验证密码长度是否符合要求
    如: 判断密码长度是否在6-18位之间 ^.{6,18}$
  • 固定电话
    如: 匹配一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0753-6816488)。0\d{2}-\d{8}|0\d{3}-\d{7}
  • 校验网址
    [a-zA-z]+://[^\s]*

以上是几种应用场景,主要是用来校验相关字段,在下一篇正则在javascript的应用中还会提到。

总结

正则的语法是很多,也很让人头疼。同一种规则也会有不同的写法,要征服正则的第一步就是自己多写多练多使用,这样才能进一步的熟练正则。以上只是简单的介绍了正则的一些用法,还有很多没有提到,有兴趣可以找相关资料进一步学习。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 2,129评论 0 9
  • 注:本篇文章只为方便查看,特此保留,如有冒犯,敬请谅解!!! 本文目标 30分钟内让你明白正则表达式是什么,并对它...
    阿杰Alex阅读 1,471评论 0 10
  • 原文:http://www.jb51.net/tools/zhengze.html 然后强迫症如我,因为我怕网页哪...
    你再不来我要下雪了阅读 827评论 1 6
  • 版本:v2.3.5 (2017-6-12) 作者:deerchao 转载请注明来源 目录 跳过目录 本文目标 如何...
    readilen阅读 941评论 2 13
  • 字体包 包含了方正系列字体,造字工房字体以及一些手写体,非常全面。一共132款。 方正兰亭系列字体 下载链接:ht...
    LuckyJing阅读 896评论 3 12