python的正则表达式

python的正则表达式跟perl语言的很像,用来处理字符串比较方便,记一下学习笔记。

一、常用方法:

测试数据:
这里是用了个json转成str的 字符串,而不是用了个json,json直接使用正则会报错的,json的字段查找还是用可爱的 jsonpath 吧。

test_json = {
    "name":"regular expression",
    "id":201920192019,
    "orders":{
        "order1":123,
        "order2":2345
    },
    "string":"regexp1234regexp78hjkl90",
    "listarr":[
        "index1=str",
        [
            2,
            3
        ],
        {
            "jsonstr1":"jsonstrD"
        }
    ],
    "special":"'''test123‘’\"!@@%^&&*"
}
test_str = json.dumps(test_json)
print "实际测试数据应该是:
{"name": "regular expression", "id": 201920192019, "special": "'''test123\u2018\u2019\"!@@%^&&*", "orders": {"order2": 2345, "order1": 123}, "listarr": ["index1=str", [2, 3], {"jsonstr1": "jsonstrD"}], "string": "regexp1234regexp78hjkl90"}"
1、match()从“头”匹配

re.match()匹配字符串,从字符串开始即匹配,如果字符串里有字串匹配,但是不是从头开始匹配,也认为没有找到指定模式,返回结果是空的

test_result_m = re.match(r"\"name\":",test_str)
print test_result_m
# re.match输出结果:None,因为匹配开头,所以没有找到匹配结果
test_result_m2 = re.match(r"{\"name\":",test_str)
print test_result_m2,test_result_m2.group()
# re.match输出结果:<_sre.SRE_Match object at 0x0000000002F1B9F0> {"name":在内存0x000000000306D988这个位置找到了  {"name": 字段

补充说明:通过match和search方法获取的字符串放在一个group里,可以直接使用group()查看,如果直接打印match或者search的返回内容,实际含义是找到字段的第一个位置

2、search()“整个”匹配

re.search()匹配字符串,不要求从开头匹配,会匹配整个字符串,直到找到第一个或者最后都没有找到结束

test_result_s = re.search(r"\"name\":",test_str)
print test_result_s,test_result_s.group()
# 直接输出re.search结果:<_sre.SRE_Match object at 0x00000000031009F0> "name":
# 这里说明在内存0x00000000031009F0这个位置找到了 "name": 字段;打印分组内容是最终结果
3、findall()找到所有

re.findall(),匹配整个字符串,找到所有匹配模式的字串,并存放在一个list里面

test_result_f = re.findall(r"23",test_str)
print test_result_f,type(test_result_f)
# 直接输出re.findall结果:['23', '23', '23', '23'] <type 'list'>
# 找到了所有匹配模式的字串,并存放在list里面
4、sub()查找替换

re.sub(regexp,substrnew,strsource,n)匹配字串并进行替换,可以指定替换次数n

test_result_sub = re.sub(r"23","TWOTHREE",test_str)
test_result_sub1 = re.sub(r"23","TWOTHREE",test_str,2)
print test_result_sub,"\n",test_result_sub1
# test_result_sub打印结果:{"name": "regular expression", "id": 201920192019, "special": "'''test1TWOTHREE\u2018\u2019\"!@@%^&&*", "orders": {"order2": TWOTHREE45, "order1": 1TWOTHREE}, "listarr": ["index1=str", [2, 3], {"jsonstr1": "jsonstrD"}], "string": "regexp1TWOTHREE4regexp78hjkl90"}
#  没有填写替换最大次数,默认是全部替换
# test_result_sub1输出结果:{"name": "regular expression", "id": 201920192019, "special": "'''test1TWOTHREE\u2018\u2019\"!@@%^&&*", "orders": {"order2": TWOTHREE45, "order1": 123}, "listarr": ["index1=str", [2, 3], {"jsonstr1": "jsonstrD"}], "string": "regexp1234regexp78hjkl90"}
#  指定替换个数=2后,只替换了从字符串开始匹配的前2个
5、re.split()从“中”切割

re.split(regexp, string, max)用来分割字符串,将string按照regexp的要求进行分割,max会指定最大分割次数,默认全部分割

二、常用匹配模式:

测试数据:

str = "we12890zxcvbnm1234 567\n[]\n23456asddvnjkl7890\nasdddd1234567a\nsd"
print str
# 打印str的样子:
we12890zxcvbnm1234 567
[]
23456vnjkl7890
asdddd1234567a
sd
1、..*.+

.会匹配除 \n 以外的任意字符;单独用.的时候代表1个任意字符,.*代表可以匹配0-n个.代表的任意字符,.+代表可以匹配1-n个.代表的任意字符

# .会匹配除\n意外的任意字符,单独用.的时候代表1个字符;.*代表可以匹配0-n个.代表的字符,.+代表可以匹配1-n个.代表的字符
print re.findall(r"(\d+).",str)
print re.findall(r"(\d*).",str)
print re.findall(r"(\d.*).",str)
print re.findall(r"(.\d.*).",str)
print re.findall(r"(.*\d.*).",str)
print re.findall(r"(.+\d.+).",str)
# 当然,*和+也可以与某个表达式/模式一起用,匹配多个表达式
print re.findall(r"(\d.)+.",str)
# 匹配结果
['12890', '1234', '56', '23456', '789', '1234567']
# (\d*).  需要后面有内容的0-n个数字内容,且不包含\n字符,所以匹配结果有空值(0个数字)
['', '', '12890', '', '', '', '', '', '', '1234', '56', '', '', '23456', '', '', '', '', '', '', '', '', '789', '', '', '', '', '', '', '1234567', '', '']
['12890zxcvbnm1234 56', '23456asddvnjkl789', '1234567']
['e12890zxcvbnm1234 56', '23456asddvnjkl789', 'd1234567']
['we12890zxcvbnm1234 56', '23456asddvnjkl789', 'asdddd1234567']
['we12890zxcvbnm1234 56', '23456asddvnjkl789', 'asdddd1234567']
['0z', '34', '56', '6a', '78', '56']
2、re.Mre.S

()可以进行多个匹配,re.M可进行多行匹配,re.S可以实现包括 \n 在内的多行匹配

# 多行匹配,但是不能越过\n
print re.findall(r"(567.*)",str,re.M)
# .默认不越过\n,re.S使.能够越过\n{}
print re.findall(r"(567.*)",str,re.S)
# 匹配非字母数字及下划线
print re.findall(r"\W(.*)",str)
# 匹配字母数字及下划线
print re.findall(r"\w(.*)",str)
# 取两组,最终结果每个list的一个元素是一个元组
print re.findall(r"(.*)\w(.*)",str)
# 输出结果:
['567', '567a']
['567\n[]\n23456asddvnjkl7890\nasdddd1234567a\nsd']
['567', '[]', '23456asddvnjkl7890', 'asdddd1234567a', 'sd']
['e12890zxcvbnm1234 567', '3456asddvnjkl7890', 'sdddd1234567a', 'd']
[('we12890zxcvbnm1234 56', ''), ('23456asddvnjkl789', ''), ('asdddd1234567', ''), ('s', '')]
3、[][^]

[]完成字符的精确匹配,[^…]匹配除了…以外的字符

# ['dd', 'dd'] 精确匹配2个d的字串
print re.findall(r"(d{2}).+",str)
# {n}精确匹配前面表达式n个连续的形式
print re.findall(r"(\d{2})",str)
# 匹配除数字以外的字符
print re.findall(r"([^(\d)])",str)
# 输出结果:
['dd', 'dd']
['12', '89', '12', '34', '56', '23', '45', '78', '90', '12', '34', '56']
['w', 'e', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ' ', '\n', '[', ']', '\n', 'a', 's', 'd', 'd', 'v', 'n', 'j', 'k', 'l', '\n', 'a', 's', 'd', 'd', 'd', 'd', 'a', '\n', 's', 'd']
4、贪婪匹配

贪婪匹配——匹配的越多越好,我们上面的例子默认使用的都是贪婪模式,在匹配模式末尾加上?表示使用非贪婪模式

print re.findall(r"dd+?",str)
print re.findall(r"dd+",str)
输出结果:
['dd', 'dd', 'dd']
['dd', 'dddd']

.


为什么在使用匹配模式的时候,总是看到正则以r开头?
因为r表示匹配原生字符串,在运行的时候不需要处理 \ 转义字符

# 举个栗子:
str_r = "\\asdfgh\\\"12345asd\\\rfgh"
print re.findall(r"\\",str_r)
# 取原生的\\,表示用了转义的\,因为\\在原始字符串中就表示用了转义的\
print re.findall("\\\\",str_r)
# 没有用原生字串,首先\\\\给python解析转义成\\,然后正则表达式再解析认为是转义后的\
# 尝试的话会发现,模式开头不用 r 的话,"\\" 会报错
# 输出结果:
['\\', '\\', '\\']
['\\', '\\', '\\']
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • Python中的正则表达式(re) import rere.match #从开始位置开始匹配,如果开头没有则无re...
    BigJeffWang阅读 7,050评论 0 99
  • re模块手册 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以...
    喜欢吃栗子阅读 3,977评论 0 13
  • 搞懂Python 正则表达式用法 Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一...
    厦热阅读 1,568评论 0 2
  • 活在虚幻中无法自拔,我一直都活在幻想中,常常在幻想着虚无缥缈的生活,可能是经常想的原因,我经常迷迷糊糊的以为那样的...
    心存妄念阅读 239评论 0 0
  • 当别人站在舞台光鲜亮丽,而你在人群中垂头丧气;当别人坐在办公楼喝着咖啡,而你在太阳下跑来跑去;当别人轻而易举的可以...
    馨语芭阅读 276评论 0 1