3.正则表达式使用基础:括号(一)

3.1分组

  • 假设有这么一个需求,我们需要匹配身份证号码。各位可以思考下怎么写正则表达式。
    身份证号码生成规则:长度15、18位数的字符串,如果是15位,则全是数字,首位不能是0;如果18位,则前17位全是数字,末尾可能是数字或者字母x,首位同样不能是0。
    很正常的,我们可以考虑两套规则:
15位:[1-9]\d{14}
18位:[1-9]\d{14}\d{2}[0-9x]
  • 但明明这2套规则前面大部分都一样,只是18位的规则后面多了3个字符串而已。这三个字符串要吗出现,要吗出现一次。有没有办法可以一套正则适应2套规则呢。这个时候就可以使用括号()进行分组了。把最后的这个规则作为整体来匹配。
  • (\d{2}[0-9x])
    因此正则表达式可以写成 [1-9]\d{14}(\d{2}[09-x])? 括号的这种功能就叫做分组。例子:希望 ab 重复一次以上,就写作 (ab)+,如果写 ab+,那么+号只限定b。
re.search(r"^ab+$","ab") != None   #=> True
re.search(r"^ab+$","abb") != None   #=> True
re.search(r"^ab+$","abab") != None   #=> False

re.search(r"^(ab)+$","ab") != None   #=> True
re.search(r"^(ab)+$","abb") != None   #=> False
re.search(r"^(ab)+$","abab") != None   #=> True

有了分组,就可以准确表示“长度只能是m或者n”

3.2多选分组

之前用表达式[1-9]\d{14}(\d{2}[09-x])?匹配身份证号,思路是把18位号码多出的3位“合并”到匹配的15位号码的表达式中。还可以有其他方式。
15位身份证号就是[1-9]开头,之后是14位数字;18位身份证的开头也是[1-9]的数字,之后是16位数字,最后是[1-9x]?。只需要匹配两种表达式中的一个,就是合法身份证。那我们可以使用多选分组。

  • 多选分组的形式是 (...|...),在括号内以 | 分割多个子表达式,这些子表达式也叫多选分支;
  • 在一个多选结构内,多选分支的数目没有限制。匹配成功时,整个多选分支被视为单个元素,只要其中某个子表达式能够匹配,整个多选结构的匹配都算成功。如果都不能匹配,则整个多选结构匹配失败。回到我们的问题上,我们就可以写2个子表达式来匹配身份证。
  • ([1-9]\d{14}|[1-9]\d{14}\d{2}[09-x]),实现的效果和之前的最后3位分组是一致的。
  • 多选结构比较常见,例如匹配IP地址。要匹配的数字是0~255。思路如下,假设只有一位,那么 \d 即可表示;如果有2位,那么 \d{2} 即可;如果有三位,那么假设第一位数字是1,则后面2位无限制,即 1\d{2} ;如果第一位不是1,而是2,那么第二位数字只能是[0-4],第三位数字无限制,即 2[0-4]\d ;如果第二位数字是5,则第三位数字只能是 [0-5] 。我们可以写表达式:
(\d|\d{2}|1\d\d|2[0-4]\d|25[0-5])

-关于多选分组,补充三点:
1.多选结构的一般表示法是(option1|option2),在多选结构中一般会同时使用()和竖线 |;但是如果没有括号,只出现竖线|,仍然是多选结构。

re.search(r"ab|cd","ab") != None  # =>True
re.search(r"ab|cd","cd") != None # =>True

括号的用来规定整个多选结构的范围,如果没有出现括号,则整个表达式视为一个多选结构,所以 ab|cd 等价于 (ab|cd),建议多选结构都写出括号。

  • 看起来 [abc] 和 (a|b|c) 一样的,实际上它们能匹配的内容确实一样,但是不推荐使用多选表达式来替代我们的字符组。理由如下:
    1.多选结构更加复杂,不便于书写简单的字符组。 [0-9] 明显比 (0|1|2|3|4|5|6|7|8|9) 简洁。
    2.多选结构每个分支长度没有限制,无法对应到字符组上。
    3.多选结构无法表示排除型字符组。
  • 多选结构的匹配顺序默认是先左侧。例如(hell|hellow),用它来匹配 hellow,结果是hell。
print(re.search(r"(jeffery|jeff)", "jeffery")).group(0)
jeffery

print(re.search(r"(jeff|jeffery)", "jeffery")).group(0)
jeff

最好避免出现相同字符的多选结构,这样匹配会造成大量回溯,影响效率。

3.3引用分组

  • 括号不仅能把有联系的元素归拢起来并分组,还有其他作用——使用括号后,正则表达式会保存每个分组真正匹配的文本,匹配完成后通过 group(num)之类的方法“引用”分组在匹配时捕获的内容。因为捕获了文本,所以这种功能叫做捕获分组。这种括号叫做捕获型括号
    注意num编号从1开始, 不给参数,默认就是0开始
result = re.search(r"(\d{4})-(\d{2})-(\d{2})"), "2010-12-22")
print(result .group(1))
2010

print(result .group(2))
12

print(result .group(3))
22

print(result .group(0))
2010-12-22

print(result .group())
2010-12-22

括号还可以嵌套,例如下面的例子,这种比较繁冗。分组的编号此时根据开括号的出现顺序来计数

manyGroups = r"(((\d{4})-(\d{2}))-(\d{2}))"
result = re.search(manyGroups, "2010-12-22")

print(result.group(0))
2010-12-22

print(result.group(1))
2010-12-22

print(result.group(2))
2010-12

print(result.group(3))
2010

print(result.group(4))
12

print(result.group(5))
22

3.3正则表达式替换

  • 这里还是以python为例子。 re.sub(pattern, replacement, string)
print(re.sub(r"[a-z]", " ","1a2b3c"))
1 2 3
上述代码是将字符串1a2b3c中的英文字母替换为一个空格
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容