python05-正则表达式(一)

正则表达式

  • python无正则表达式,通过别的模块re(regex模块)应用过来

    • import re # 引入re模块调用正则表达式
  • 字符匹配

    • 普通字符:如英文字母a-zA-Z和其他字符
    regex = 'apple'
    ret = re.findall(regex, 'i have a apple , i have a pen, apple pen ?')
    print(ret)
    ======>
    ['apple', 'apple']
    
    • 元字符:被赋予特殊含义的字符

      • .:通配符(任意字符)
      • ^:是否以某个字符开头
      • $:是否以某个字符结尾
      ret = re.findall('.', 'string')
      print(ret) # ['s', 't', 'r', 'i', 'n', 'g']
      
      ret = re.findall("^apple", 'apple is one kind of fruit')
      print(ret) # ['apple']
      ret = re.findall("^apple", 'the apple is one kind of fruit')
      print(ret) # []
      
      ret = re.findall('pen$', 'i have a apple , i have a pen, apple pen ?')
      print(ret) # []
      ret = re.findall('pen$', 'i have a apple , i have a pen, apple pen')
      print(ret) # ['pen']
      
      • * :出现0次或n次
      • +:出现1次或n次
      • ?:出现0次或1次
      • {}:
        • {x}:出现x次
        • {x,}:至少出现x次
        • {x,y}:出现x-y次之间
      ret = re.findall('apple*', 'i have an apple , not applee or appl')
      print(ret) # ['apple', 'applee', 'appl']
      ret = re.findall('apple+', 'i have an apple , not applee or appl')
      print(ret) # ['apple', 'applee']
      ret = re.findall('apple?', 'i have an apple , not applee or appl')
      print(ret) # ['apple', 'apple', 'appl']
      ret = re.findall('apple{2,4}','i have an apple , not appleee or appleeee')
      print(ret) # ['appleee', 'appleeee']
      
      • \:转义
        • 后面如果接元字符,则将元字符转为普通字符
        • 后面接普通字符,则实现该字符特殊功能
        • 后面接序号,引用所匹配的字符串
      
      
        • -:表示范围
        • ^:取反
        • \:转义
          • \d:数字[1-9]
          • \D:非数字[^1-9]
          • \w:字母数字下划线[a-zA-Z_]
          • \W:非字母数字下划线[^a-zA-Z_]
          • \s:空白字符[\t\n\r\f\v]
          • \S:非空白字符[\t\n\r\f\v]
          • \b:匹配单个单词边界,就是单词间间隔,边界不一定是空格,特殊字符也可以
        • ():组
      ret = re.findall('\d', '123sadf@#$')
      print(ret) # ['1', '2', '3']
      ret = re.findall('[^\d]+','asdf123d5esd234')
      print(ret) # ['asdf', 'd', 'esd']
      
      ret = re.search(r'(alex)(eric)com\1', 'alexericcomalex').group()
      print(ret) # alexericcomalex
      
      • 非贪婪匹配
        • 一般 *和+匹配的时候都按照最多的原则匹配获取(贪婪匹配)
        • 如果想要按最少匹配,则加上?但是有条件
      \d+?:一个或者多个,取最少的1个
      \d*?:0个或者多个,取最少的0个
      'a(\d+?)':可以用非贪婪匹配
      'a(\d+?)b'不可以用非贪婪模式,因为后面接了字符
      
  • re包方法:

    • findall():查找所有,返回一个列表
    • search():找到第一个就不往下找了
    • match():只匹配开头的内容
  • search() 和 match()如果匹配成功或返回一个对象,该对象方法

    • group():返回组的内容
    • groups():根据regex的分组情况返回tuple
    ret = re.search('(ap)+(pl)+e', 'apple apaplele').group()
    print(ret) # apple
    ret = re.search('(ap)+(pl)+e', 'apple apaplele').groups()
    print(ret) # ('ap', 'pl')
    
    • start():匹配到的第一个索引位置
    • end():匹配的结束位置索引
    • span():start 和 end索引之间的区间
    ret = re.search('(ap)+(pl)+e', 'apple apaplele')
    print(ret.start())  # 从开始
    print(ret.end())    # index = 4结束,开区间为5
    print(ret.span())   #[0,5)
    
    a = '123abc456'
    regex = '([\d]*)([a-zA-Z]*)([\d]*)'
    ret = re.search(regex, a)
    print(ret.group()) # 默认为0
    print(ret.group(1))
    print(ret.group(2))
    print(ret.group(3))
    print(ret.groups())
    """
    123abc456
    123
    abc
    456
    ('123', 'abc', '456')
    """
    a = '123abc456'
    regex = '([\d])*([a-zA-Z])*([\d])*'
    ret = re.search(regex, a)
    print(ret.group()) # 默认为0
    print(ret.group(1))
    print(ret.group(2))
    print(ret.group(3))
    print(ret.groups())
    """
    123abc456
    3
    c
    6
    ('3', 'c', '6')
    """
    
  • re的其他方法:

    • sub(pattern, repl, string, max=0):替换
      • max表示替换的最大次数,默认为0,不限次数
    ret = re.sub('g.t', 'have', 'i get a pen, i got a pen, i gun a pen')
    print(ret) # i have a pen, i have a pen, i gun a pen
    
    • subn(pattern, repl, string):替换,返回的结果带替换次数num
    ret = re.subn('g.t', 'have', 'i get a pen, i got a pen, i gun a pen')
    print(ret) # ('i have a pen, i have a pen, i gun a pen', 2)
    
    • compile(regext):编译.传入一个正则表达式,返回一个匹配器
    regex = re.compile('\w*oo\w*')
    ret = regex.findall('JGood is a handsome boy, he is cool')
    print(ret) # ['JGood', 'cool']
    
    • split:切割
    ret = re.split('\d', 'one1two2three3four4')
    print(ret) # ['one', 'two', 'three', 'four', '']
    
  • IP正则表达式

# IP 正则表达式
regex = '(([01]?\d?\d|2[0-4]\d|25\d)\.){3}([01]?\d?\d|2[0-4]\d|25\d)'
ret = re.search(regex, '192.168.97.196').group()
print(ret) # 192.168.97.196
  • 原生字符串

    • 执行下面的代码会报错(在python中)
    file = open('C:\tmp\abc.txt', mode='r')
    # OSError: [Errno 22] Invalid argument: 'C:\tmp\x07bc.txt'
    
    • 原因:

      • 在python中,反斜杠\有转义的含义,当遇到\a根据ascii码表,会转为有特殊含义的字符0x07响铃符BEL
    • 解决:

      • file = open(r'C:\tmp\abc.txt', mode='r')
      • r为rawString = 原生字符串,表示传入python的字符是原生的,没有特殊的含义
    • 执行下面的代码会报错(在正则中)

    re.findall('\', 'abc\123') # 编译的时候就会出错
    
    • 原因:

      • 反斜杠\在正则中也有转义的效果,代表后面接的字符有特殊含义
      • 所以使其表示反斜杠应写成\\(双反斜杠,第一个用作转义)
       re.findall('\\', 'abc\123') # 执行会报错
      
      • 代码在正则下匹配是正确的,但是执行代码,程序会报错
      • 原因:
        • 虽然正则表示的写法是正确的,但是程序是运行在python下的
        • 在python代码中,我们写的是\\(双反斜杠)表示反斜杠,这只是在python代码中
        • 当python代码传递过去给正则表达式,其实是一条反斜杠的转义符,但是正确的表达式需要2条,所以python代码需要写成4条反斜杠才能匹配成功
      • 修改代码后为:
       re.findall('\\\\', 'abc\123') # ok
      
    • 原生字符串r的产生

      • 通过上面的写法,会很麻烦,于是就产生了远程字符串的概念
      ret = re.findall(r'\\', r'abc\123') 
      # ['\\']其中一个是转义,表示一个反斜杠
      
      • 代码中,r表示后面字符串的内容就是代表反斜杠,没有别的意思,代码执行的时候,python把2个反斜杠原封不动的传给正则,正则拿到反斜杠,第一个用作第二个的转义
      • 这样代码执行的时候会更加直观
    • 执行下面代码

    ret = re.findall('\\d', 'w3t5e7')
    print(ret)
    ret = re.findall(r'\d', 'w3t5e7')
    print(ret)
    ret = re.findall('\d', 'w3t5e7')
    print(ret)
    ========
    ['3', '5', '7']
    ['3', '5', '7']
    ['3', '5', '7']
    
    • 原因:
      • 第一个传入两个反斜杠,python转义之后,传到正则后是一个反斜杠
      • 一个反斜杠转义d,表示数字
      • 第二个通过r指定反斜杠是原生字符串,反斜杠直接传到正则表达式转义d
      • 第三个理论上会报错,但是反斜杠d在ascii码表上没有特殊含义,python内部会将其原封不动传给正则表达式,但是如果遇到时\a之类的就报错了
      • 所以严格来说按12的写才是正确的
  • findall用法

    • findall优先把组里的内容取出来
    regex = 'www.(baidu|youku).com'
    ret = re.findall(regex, 'www.baidu.com')
    print(ret) # ['baidu']
    
    • 如果要去掉优先捕获
    regex = 'www.(?:baidu|youku).com'
    ret = re.findall(regex, 'www.baidu.com')
    print(ret) # ['www.baidu.com']
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 正则表达式(二) re模块(regex) python中没有正则表达式的函数,需要引入内置的re模块 re模块方法...
    AndroidCat阅读 329评论 0 0
  • 1.正则表达式概述 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regula...
    TENG书阅读 799评论 0 1
  • (一)定义 正则表达式是对字符串(包括普通字符(例如,a 到 z之间的字母)和特殊字符(称为“元字符”))操作的一...
    a荷包蛋阅读 494评论 0 0
  • re模块手册 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以...
    喜欢吃栗子阅读 3,902评论 0 13
  • 一说到曹操大家肯定都想到奸炸,这可能是曹操在三国的人气不好。有时演个戏,曹操一败观众就连口称赞,一听刘备打了败...
    kanzihan阅读 259评论 0 0