当前位置: 首页 > news >正文

十七. Python基础(17)--正则表达式

十七. Python基础(17)--正则表达式

1 ● 正则表达式

定义: Regular expressions are sets of symbols that you can use to create searches for finding and replacing patterns of text.

零宽断言(zero width assertion):

零宽断言--不是去匹配字符串文本,而是去匹配位置(开头, 结尾也是位置)

常见的:

起始位置^(单行)/A(多行)

末尾位置 $(单行)/Z(多行)

单词边界/b, 非单词边界/B等等。

(?=exp): 匹配后面是exp的位置

(?!exp): 匹配后面不是exp的位置

(?<=exp): 匹配前面是exp的位置

(?<!exp): 匹配前面不是exp的位置

(?#exp): 表示括号内是注释

 

 

区别于异常处理中的"断言"

参考文章:

正则基础

http://www.cnblogs.com/Eva-J/articles/7228075.html#_label10

http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

http://www.runoob.com/regexp/regexp-metachar.html

向后引用(回溯引用)以及零宽断言

http://www.cnblogs.com/linux-wangkun/p/5978462.html

http://www.cnblogs.com/leezhxing/p/4333773.html

 

2 ● 正则的难点示例

\b匹配这样的位置:

简单来说: 单词边界(word boundary)

具体来说: 它的前一个字符和后一个字符不全是(一个是, 一个不是或不存在)\w.

例如: a!bc, 经过如下替换:

结果变成:

!bc

 

\B匹配这样的位置:

简单来说: 非单词边界(not word boundary)

例如: ab cd    ef, 经过如下替换:

结果变成:

aAAAb cAAAd    eAAAf

 

abc

ab,c

结果是:

AaAbAcA

AaAb,AcA

 

匹配不包括逗号的行

abcd

abcd,

,abcd

ab,cd

 

^((?!,).)*$表示不包括逗号","的行

^((?<!,).)*$不能表示不包括逗号的行, 因为会把"abc,"这种情况也错误匹配上

不包括字母的行:

^((?![A-Za-z]).)*$

 

不包括数字的行:

^((?!^[0-9]).)*$

 

不是开头的'''

(?<!(^))'''或者(?<!^)'''

 

匹配括号中的内容, 但是不包括括号:

(?<=\()\S+(?=\))

 

 

(?#expr)

2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)

 

贪婪(greedy)与非贪婪(non-greedy)

贪婪尽可能多地重复

非贪婪尽可能少地重复

 

3 ● python反向引用(back-reference)

import re

text = "Hello Arroz, Nihao Arroz"

rep = re.sub(r"Hello (\w+), Nihao \1", "GOOD", text) # GOOD

rep = re.sub(r"Hello (\w+), Nihao \1", "\g<1>", text) # Arroz

rep = re.sub(r"Hello (\w+), Nihao \1", "\g<0>", text) # Hello Arroz, Nihao Arroz

(...) matches whatever regular expression is inside the parentheses, and indicates the start and end of a group.

\g<N> 是用来反向引用(backreferences)的;

如果N是正数, 那么\g<N> 匹配(对应) 从左边数起,第N个括号里的内容; 例如上面的\g<1>匹配Arroz

如果N0,那么\g<N> 匹配(对应) 整个字符串的内容; 例如上面的\g<0>匹配Hello Arroz, Nihao Arroz

详见: http://blog.5ibc.net/p/80058.html

 

4 ● 反向引用的案例

match(pattern, string, flags=0) returns the first match(返回_sre.SRE_Match对象) from the beginning of the string, if any; otherwise, a "NoneType" object.

search(pattern, string, flags=0) returns the first match(返回_sre.SRE_Match对象) within the whole string, if any; otherwise, a "NoneType" object.

flags    标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

 

findall() returns a list of all non-overlapping matches(in the tuple form), if any; otherwise, an empty list.

finditer() return an iterator yielding match objects over all non-overlapping matches for the RE pattern in string, if any; otherwise, an empty generator.

 

match(string[, pos[, endpos]])方法在字符串开头或指定位置进行搜索,模式必须出现在字符串开头或指定位置;

search(string[, pos[, endpos]])方法在整个字符串或指定范围中进行搜索;

findall(string[, pos[, endpos]])方法在字符串指定范围中查找所有符合正则表达式的字符串并以列表形式返回。

m.group() == m.group(0) == 返回模式(pattern)匹配的所有字符,与括号无关

m.group(N) 返回第N组括号(N个子模式(subpattern))匹配的字符

m.groups() tuple的格式, 返回所有括号(子模式)匹配的字符,== (m.group(0), m.group(1), ...)

import re

pat = re.compile(r"(\d{4})-(\d{2})-(\d{2})")

m1 = re.match(pat, "2017-09-10, 2017-09-11")

print(m1.groups()) # ('2017', '09', '10')

print(m1.group()) # '2017-09-10'

print(m1.group(0)) #'2017-09-10'

'''

m1.group(1) #'2017'

m1.group(2) # '09'

m1.group(1,2) #('2017', '09')

m1.group(3) # '10'

m1.group(4)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

IndexError: no such group

'''

 

m2 = re.search(pat, "2017-09-10, 2017-09-11")

m2.groups() # ('2017', '09', '10')

m2.group() # '2017-09-10'

'''

m2.group(0) # '2017-09-10'

m2.group(1) # '2017'

m2.group(2) # '09'

m2.group(3) # '10'

m2.group(4)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

IndexError: no such group

'''

 

lst = re.findall(pat, "2017-09-10, 2017-09-11")

print(lst)

# [('2017', '09', '10'), ('2017', '09', '11')]

 

it = re.finditer(pat, "2017-09-10, 2017-09-11")

print(it) # <callable_iterator object at 0x0000000002943A20>

print('--------------')

 

for matchnum, match in enumerate(it):

    print(match.group())

    print(match.groups())

    for group_num in range(0, len(match.groups())):

        group_num +=1

        print(match.group(group_num))

'''

2017-09-10

('2017', '09', '10')

2017

09

10

2017-09-11

('2017', '09', '11')

2017

09

11

'''

 

5 ● 命名分组(named grouping)

反斜杠加g以及中括号内一个名字,即:\g<name>,对应着命了名的组,named group

(?P<name>expr)是分组(grouping): 除了原有的编号外, 再给匹配到的字符串expr指定一个额外的别名

(?P=expr)是反向引用/回溯(back reference): 引用别名为<name>的分组匹配到的字符串

 

text = "Hello Arroz, Nihao Arroz"

ret = re.sub(r"Hello (?P<name>\w+), Nihao (?P=name)", "\g<name>",text)

print(ret) # Arroz

注意: (?P=name)是反向引用(reference), (?<name>)

import re

m = re.search(r"\d{4}-(?P<na>\d{2})-\d{2}", "2006-09-03")

print(m.group('na')) # 09

import re

m = re.search(r'(\d{4})-(?:\d{2})-(\d{2})', "2006-09-03") # Non-capturing group(非捕获组)

m.groups() # ('2006', '03')

m.group(1) # '2006'

m.group(2) # '03' # (?:\d{2})这一组被忽略

m.group(3)

'''

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

IndexError: no such group

'''

 

MatchObject的另外几个方法:

groupdict(default=None):返回包含匹配的所有命名子模式内容的字典

start([group]):返回指定子模式内容的起始位置

end([group]):返回指定子模式内容的结束位置的前一个位置

span([group]):返回一个包含指定子模式内容起始位置和结束位置前一个位置的元组。

import re

text = "Hello Arroz, Nihao Alex"

pat=re.compile(r"Hello (?P<name1>\w+), Nihao (?P<name2>\w+)")

mo= re.search(pat, text)

print(mo.group('name1')) # Arroz

print(mo.groupdict())    # {'name1': 'Arroz', 'name2': 'Alex'}

print(mo.span()) # (0, 23)

print(mo.span(0)) # (0, 23)

print(mo.span(1)) # (6, 11)

print(mo.start(1)) # 6

print(mo.end(1)) # 11

print(mo.span(2)) # (19, 23)

# fullmatch(pattern, string, flags=0) 尝试把模式作用于整个字符串,返回match对象或None

import re

text = "Hello Arroz, Nihao Alex"

pat=re.compile(r"Hello (?P<name1>\w+), Nihao (?P<name2>\w+)")

is_full_match = re.fullmatch(pat, text)

print("isfullmatch:", is_full_match)

# isfullmatch: <_sre.SRE_Match object; span=(0, 23), match='Hello Arroz, Nihao Alex'>

# 如果不完全匹配, 返回:isfullmatch: None

# escape(string)    将字符串中所有的非字母, 非数字字符转义(escape all non-alphanumerics)

print(re.escape('http://www.py thon.org'))

# http\:\/\/www\.py\ thon\.org→Pycharm的结果

# 'http\\:\\/\\/www\\.py\\ thon\\.org'→cmd的结果

# expand(template) 将匹配到的分组代入template中然后返回。template中可以使用 \id \g<id> \g<name> 引用分组。id为捕获组的编号,name为命名捕获组的名字。

import re

s="abcdefghijklmnopqrstuvwxyz"

pattern=r'(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)'

m=re.search(pattern,s)

print(m.expand(r'\1'), m.expand(r'\10'), m.expand(r'\g<10>'))

# a j j

 

# purge() 清空正则表达式缓存

 

 

6 ● 文本编辑器(EmEditor, NotePad++)中匹配汉字字符

Python中匹配汉字字符, 用平时见到的统一字名的形式就可以了:

[\u4e00-\u9fa5]

但是在文本编辑器(EmEditor, NotePad++), 需要把上面的形式改为(x表示十六进制)

[\x{4e00}-\x{9fa5}]

或者:

[-]

就可以实现匹配中文了.

 

单独的统一字名加不加中括号都可以.

详见:http://www.crifan.com/answer_question_notepadplusplus_regular_expression_match_chinese_character

 

● 补充

\num    此处的num是一个正整数。例如,"(.)\1"匹配两个连续的相同字符, abccde

\f    换页符匹配

 

转载于:https://www.cnblogs.com/ArrozZhu/p/8393726.html

相关文章:

  • 网络舆论舆情监测怎么做的系统技术解决办法
  • 基于区域的目标检测——细粒度
  • 网络舆情分析的三个步骤及具体实施方案
  • 近期某一事件或某一话题的舆情怎么监测的系统技术解决方法
  • 在Unity中实现鼠标拖拽物体,滚轮控制物体远近的效果
  • 网络舆论监测分析怎么做?舆情软件技术解决办法
  • javaScript第二篇
  • 网络舆情监测与分析工作怎么做好的平台解决办法
  • zookeeper的节点类型
  • 网上舆情的风险与危机怎么监测?系统技术解决方案参考
  • Python之函数的本质、闭包、装饰器
  • 网络舆情总结汇报报告如何撰写的方法技巧
  • Python--进阶处理2
  • 重大策略措施出台舆情风险评估工作怎么做的措施及方案
  • 14.leetcode67_add_binary
  • “大数据应用场景”之隔壁老王(连载四)
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 10个确保微服务与容器安全的最佳实践
  • Angular6错误 Service: No provider for Renderer2
  • AngularJS指令开发(1)——参数详解
  • DataBase in Android
  • gulp 教程
  • HTTP那些事
  • Iterator 和 for...of 循环
  • Js基础知识(四) - js运行原理与机制
  • laravel 用artisan创建自己的模板
  • LintCode 31. partitionArray 数组划分
  • MYSQL 的 IF 函数
  • opencv python Meanshift 和 Camshift
  • Spring Cloud Feign的两种使用姿势
  • 翻译:Hystrix - How To Use
  • 浮现式设计
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 如何利用MongoDB打造TOP榜小程序
  • 入门到放弃node系列之Hello Word篇
  • 使用agvtool更改app version/build
  • 数组大概知多少
  • 我有几个粽子,和一个故事
  • k8s使用glusterfs实现动态持久化存储
  • #stm32整理(一)flash读写
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (一)基于IDEA的JAVA基础1
  • (转)ObjectiveC 深浅拷贝学习
  • (转)甲方乙方——赵民谈找工作
  • .NET delegate 委托 、 Event 事件
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .net wcf memory gates checking failed
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET/C# 使窗口永不获得焦点