python正则相关

1.1 基础语法

 (1) 常用元字符

语法描述
\b匹配单词的开始或结束
\d匹配数字
\s匹配任意不可见(空格、换行符、制表符等等),等价于[\f\n\r\t\v].
\w匹配数字任意Unicode字符集,包括字母、数字、下划线、汉字等
.匹配除换行符(\n)以外的任意字符
^或\A匹配字符串或行的起始位置
$或\Z匹配字符串或行的结束位置

 (2) 限定词(又叫量词)

语法描述
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或者更多次
{n,m}重复n到m次

 (3) 常用反义词

语法描述
\B匹配非单词的开始或结束
\D匹配非数字
\S匹配任意可见的字符,[^\f\n\r\t\v]
\W匹配任意非Unicode字符集
[^abc]除a、b、c以外的任意字符

 (4) 字符族

语法描述
[abc]a、b或c
[^abc]除a、b、c以外的任意字符
[a-zA-Z]a到z或A到Z
[a-d[m-p]]a到d或m到p,即a-dm-p
[a-z&&[def]]d、e或f(交集)
[a-z&&[^bc]]a到z,除了b和c:ad-z
[a-z&&[^m-p]]a到z,减去m到p:a-lq-z

以上便是正则的基础内容,下面来写两个例子看下:

s='123abc你好'
re.search('\d',s).group()
re.search('\w+',s).group()

结果

123
123abc你好

1.2 修饰符
 修饰符在各语言中也是有差异的
python中的修饰符

语法描述
re.A匹配ASCLL字符类,影响\W,\w,\b,\B,\d,\D
re.l忽略大小写
re.L做本地化识别匹配(这个极少极少使用)
re.M多行匹配,影响^和$
re.S使.匹配包括换行符(\n)在内的所有字符
re.U匹配Unicode字符集。与re.A相对,这是默认设置
re.X忽略空格和#后面的注释以获得看起来更易懂的正则

(1) re.A
修饰符A使\w只匹配ASCLL字符,\W匹配非ASCLL字符。

s='123abc你好'
re.search('\w+',S,re.A).group()
re.search('\W+',S,re.A).group()

结果

123abc
你好

但是描述中还有\d\D,数字不都是ASCLL字符吗?这是什么意思?别忘了,还有全角和半角!

s='0123456789'#全角数字
re.search('\d+',s,re.U).group()

结果

0123456789

(2) re.M
多行匹配的模式其实也不常用,很少有一行行规则整的数据

s='aaa\r\nbbb\r\nccc'

re.findall('^[\s\w]*?$',s)
re.findall('^[\s\w]*?$',s,re.M)

结果

['aaa\r\nbbb\r\nccc']   #单行模式
['aaa\r','bbb\r','ccc'] #多行模式

 (3) re.S
这个简单,直接看例子

s='aaa\r\nbbb\r\nccc'

re.findall('^.*',s)
re.findall('^.*',s,re.S)

结果

['aaa\r']
['aaa\r\n\bbb\r\nccc']

 (4)re.X
用法如下:

rc = re.compile(r"""
\d+ # 匹配数字
# 和字母
[a-zA-Z]+
""", re.X)
rc.search('123abc').group()

结果:

123abc

注意,用了 X 修饰符后,正则中的所有空格会被忽略,包括正则里面的原本有用的空格。如果正则中有需要使用空格,只能用 \s 代替。

 (5)(?aiLmsux)
修饰符不仅可以代码中指定,也可以在正则中指定。(?aiLmsux) 表示了以上所有的修饰符,具体用的时候需要哪个就在 ? 后面加上对应的字母,示例如下,
(?a) 和 re.A 效果是一样的:

s = '123abc你好'
re.search('(?a)\w+', s).group()
re.search('\w+', s, re.A).group()

结果是一样的:

123abc
123abc

1.3、贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。

s = 'aabab'
re.search('a.*b', s).group()    # 这就是贪婪
re.search('a.*?b', s).group()   # 这就是懒惰

结果:

aabab
aab

简单来说:

  • 所谓贪婪,就是尽可能 多 的匹配;
  • 所谓懒惰,就是尽可能 少 的匹配。
  • *、+、{n,} 这些表达式属于贪婪;
  • *?、+?、{n,}? 这些表达式就是懒惰(在贪婪的基础上加上 ?)。

2、正则进阶

2.1、捕获分组

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

注意:在其他语言或者网上的一些正则工具中,分组命名的语法是 (?exp) 或 (?'name'exp) ,但在 Python 里,这样写会报错:This named group syntax is not supported in this regex dialect。Python 中正确的写法是: (?Pexp)

示例一:
分组可以让我们用一条正则提取出多个信息,例如:

s = '姓名:张三;性别:男;电话:138123456789'
m = re.search('姓名[::](\w+).*?电话[::](\d{11})', s)
if m:
    name = m.group(1)
    phone = m.group(2)
    print(f'name:{name}, phone:{phone}')

结果:

name:张三, phone:13812345678

示例二:
(?P<name>exp) 有时还是会用到的, (?P=name) 则很少情况下会用到。我想了一个(?P=name) 的使用示例,给大家看下效果:

s = '''
<name>张三</name>
<age>30</age>
<phone>138123456789</phone>
'''

pattern = r'<(?P<name>.*?)>(.*?)</(?P=name)>'
It = re.findall(pattern, s)

结果:

[('name', '张三'), ('age', '30'), ('phone', '138123456789')]

2.2、零宽断言

语法描述
(?=exp)匹配exp前面的位置
(?<=exp)匹配exp后面的位置
(?!exp)匹配后面跟的不是exp的位置
(?<!exp)匹配前面不是exp的位置

注意:正则中常用的前项界定 (?<=exp) 和前项否定界定 (?<!exp) 在 Python 中可能会报错:look-behind requires fixed-width pattern,原因是 python 中 前项界定的表达式必须是定长的,看如下示例:

(?<=aaa)        # 正确
(?<=aaa|bbb)    # 正确
(?<=aaa|bb)     # 错误
(?<=\d+)        # 错误
(?<=\d{3})      # 正确

2.3、条件匹配
这大概是最复杂的正则表达式了。语法如下:

语法描述
(?(id/name)yes!no)如果指定分组存在,则匹配yes模式,否则匹配no模式

此语法极少用到,印象中只用过一次。
(ps:表格内语法错误 不是"!"改为"|")
以下示例的要求是:如果以 _ 开头,则以字母结尾,否则以数字结尾。

s1 = '_abcd'
s2 = 'abc1'

pattern = '(_)?[a-zA-Z]+(?(1)[a-zA-Z]|\d)'

re.search(pattern, s1).group()
re.search(pattern, s2).group()

结果:

_abcd
abc1

2.4、findall

Python 中的 re.findall 是个比较特别的方法。我们看这个方法的官方注释:

Return a list of all non-overlapping matches in the string.

If one or more capturing groups are present in the pattern, return 
a list of groups; this will be a list of tuples if the pattern 
has more than one group.

Empty matches are included in the result.

简单来说,就是

  • 如果没有分组,则返回整条正则匹配结果的列表;
  • 如果有 1 个分组,则返回分组匹配到的结果的列表;
  • 如果有多个分组,则返回分组匹配到的结果的元组的列表。
    看下面的例子:
s = 'aaa123bbb456ccc'

re.findall('[a-z]+\d+', s)          # 不包含分组
re.findall('[a-z]+(\d+)', s)        # 包含一个分组
re.findall('([a-z]+(\d+))', s)      # 包含多个分组
re.findall('(?:[a-z]+(\d+))', s)    # ?: 不捕获分组匹配结果

结果:

['aaa123', 'bbb456']
['123', '456']
[('aaa123', '123'), ('bbb456', '456')]
['123', '456']

零宽断言中讲到 Python 中前项界定必须是定长的,这很不方便,但是配合 findall 有分组时只取分组结果的特性,就可以模拟出非定长前项界定的效果了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台采用apache服务器下的cgi处理c语言做微信小程序后台逻辑的脚本映射。PC端的服务器和客户端都是基于c语言写的。采用mysql数据库进行用户数据和聊天记录的存储。.zip C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值