GVKun编程网logo

如何在Python的列表理解中使用正则表达式?

10

最近很多小伙伴都在问如何在Python的列表理解中使用正则表达式?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Python中使用正则表达式、Python如何在带条件的列表理解中

最近很多小伙伴都在问如何在Python的列表理解中使用正则表达式?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Python中使用正则表达式、Python如何在带条件的列表理解中使用多个for循环、python正则表达式及使用正则表达式的例子、可以在python的列表理解中使用多个条件吗?等相关知识,下面开始了哦!

本文目录一览:

如何在Python的列表理解中使用正则表达式?

如何在Python的列表理解中使用正则表达式?

我正在尝试在单词列表中查找字符串的所有索引位置,并且希望将值作为列表返回。我想查找字符串,如果它是独立的,或者在标点符号之前或之后,但是如果它是较大单词的子字符串,则不会。

以下代码仅捕获“ cow”,而未同时捕获“ test; cow”和“ cow”。

myList = [''test;cow'', ''one'', ''two'', ''three'', ''cow.'', ''cow'', ''acow'']myString = ''cow''indices = [i for i, x in enumerate(myList) if x == myString]print indices>> 5

我尝试将代码更改为使用正则表达式:

import remyList = [''test;cow'', ''one'', ''two'', ''three'', ''cow.'', ''cow'', ''acow'']myString = ''cow''indices = [i for i, x in enumerate(myList) if x == re.match(''\W*myString\W*'', myList)]print indices

但这会产生错误:预期的字符串或缓冲区

如果有人知道我在做什么错,我会很高兴听到。我感觉这与我在期望使用字符串时尝试在其中使用正则表达式的事实有关。有解决方案吗?

我正在寻找的输出应为:

>> [0, 4, 5]

谢谢

答案1

小编典典

您无需将结果分配matchx。而且您的比赛应该进行x而不是list

另外,您需要使用re.search代替re.match,因为您的regex模式''\W*myString\W*''将不匹配第一个元素。那是因为test;与不匹配\W*。实际上,您只需要测试紧跟的后跟字符,而不是完整的字符串。

因此,您可以word boundaries在字符串周围使用:

pattern = r''\b'' + re.escape(myString) + r''\b''indices = [i for i, x in enumerate(myList) if re.search(pattern, x)]

Python中使用正则表达式

Python中使用正则表达式

字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。

所以我们判断一个字符串是否是合法的Email的方法是:

  1. 创建一个匹配Email的正则表达式;

  2. 用该正则表达式去匹配用户的输入来判断是否合法。

因为正则表达式也是用字符串表示的,所以,我们要首先了解如何用字符来描述字符。

在正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配一个数字,\w可以匹配一个字母或数字,所以:

  • ''00\d''可以匹配''007'',但无法匹配''00A''

  • ''\d\d\d''可以匹配''010''

  • ''\w\w\d''可以匹配''py3''

.可以匹配任意字符,所以:

  • ''py.''可以匹配''pyc''''pyo''''py!''等等。

要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:

来看一个复杂的例子:\d{3}\s+\d{3,8}

我们来从左到右解读一下:

  1. \d{3}表示匹配3个数字,例如''010''

  2. \s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配'' '''' ''等;

  3. \d{3,8}表示3-8个数字,例如''1234567''

综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

如果要匹配''010-12345''这样的号码呢?由于''-''是特殊字符,在正则表达式中,要用''\''转义,所以,上面的正则是\d{3}\-\d{3,8}

但是,仍然无法匹配''010 - 12345'',因为带有空格。所以我们需要更复杂的匹配方式。

进阶

要做更精确地匹配,可以用[]表示范围,比如:

  • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;

  • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如''a100''''0_Z''''Py3000''等等;

  • [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;

  • [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

A|B可以匹配A或B,所以(P|p)ython可以匹配''Python''或者''python''

^表示行的开头,^\d表示必须以数字开头。

$表示行的结束,\d$表示必须以数字结束。

你可能注意到了,py也可以匹配''python'',但是加上^py$就变成了整行匹配,就只能匹配''py''了。

re模块

有了准备知识,我们就可以在Python中使用正则表达式了。Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,所以要特别注意:

s = ''ABC\\-001'' # Python的字符串
# 对应的正则表达式字符串变成:
# ''ABC\-001''

因此我们强烈建议使用Python的r前缀,就不用考虑转义的问题了:

s = r''ABC\-001'' # Python的字符串
# 对应的正则表达式字符串不变:
# ''ABC\-001''

先看看如何判断正则表达式是否匹配:

>>> import re
>>> re.match(r''^\d{3}\-\d{3,8}$'', ''010-12345'') <_sre.SRE_Match object; span=(0, 9), match=''010-12345''> >>> re.match(r''^\d{3}\-\d{3,8}$'', ''010 12345'') >>> 

match()方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None。常见的判断方法就是:

test = ''用户输入的字符串''
if re.match(r''正则表达式'', test):
    print(''ok'')
else: print(''failed'') 

切分字符串

用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:

>>> ''a b   c''.split('' '')
[''a'', ''b'', '''', '''', ''c''] 

嗯,无法识别连续的空格,用正则表达式试试:

>>> re.split(r''\s+'', ''a b   c'')
[''a'', ''b'', ''c''] 

无论多少个空格都可以正常分割。加入,试试:

>>> re.split(r''[\s\,]+'', ''a,b, c  d'')
[''a'', ''b'', ''c'', ''d''] 

再加入;试试:

>>> re.split(r''[\s\,\;]+'', ''a,b;; c  d'')
[''a'', ''b'', ''c'', ''d''] 

如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。

分组

除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。比如:

^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:

>>> m = re.match(r''^(\d{3})-(\d{3,8})$'', ''010-12345'')
>>> m
<_sre.SRE_Match object; span=(0, 9), match=''010-12345''> >>> m.group(0) ''010-12345'' >>> m.group(1) ''010'' >>> m.group(2) ''12345'' 

如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来。

注意到group(0)永远是原始字符串,group(1)group(2)……表示第1、2、……个子串。

提取子串非常有用。来看一个更凶残的例子:

>>> t = ''19:05:30''
>>> m = re.match(r''^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$'', t)
>>> m.groups() (''19'', ''05'', ''30'') 

这个正则表达式可以直接识别合法的时间。但是有些时候,用正则表达式也无法做到完全验证,比如识别日期:

''^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$''

对于''2-30''''4-31''这样的非法日期,用正则还是识别不了,或者说写出来非常困难,这时就需要程序配合识别了。

贪婪匹配

最后需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0

>>> re.match(r''^(\d+)(0*)$'', ''102300'').groups()
(''102300'', '''') 

由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。

必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

>>> re.match(r''^(\d+?)(0*)$'', ''102300'').groups()
(''1023'', ''00'') 

编译

当我们在Python中使用正则表达式时,re模块内部会干两件事情:

  1. 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;

  2. 用编译后的正则表达式去匹配字符串。

如果一个正则表达式要重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:

>>> import re
# 编译:
>>> re_telephone = re.compile(r''^(\d{3})-(\d{3,8})$'') # 使用: >>> re_telephone.match(''010-12345'').groups() (''010'', ''12345'') >>> re_telephone.match(''010-8086'').groups() (''010'', ''8086'') 

编译后生成Regular Expression对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用给出正则字符串。

小结

正则表达式非常强大,要在短短的一节里讲完是不可能的。要讲清楚正则的所有内容,可以写一本厚厚的书了。如果你经常遇到正则表达式的问题,你可能需要一本正则表达式的参考书。

Python如何在带条件的列表理解中使用多个for循环

Python如何在带条件的列表理解中使用多个for循环

x = ...中语句的顺序有些混乱;您的if应该过滤要包括的值,而不是要使用的两个替代值中的哪一个。而且:不要在列表理解中使用append附加到另一个列表!相反,列表理解本身应该是您的结果。

def solve(first,last):
    weekends = [c.month_abbr[m] for y in range(first,last+1)
                                for m in [1,3,5,7,8,10,12]
                                if c.weekday(y,m,1) == 4]
    return weekends[0],weekends[-1],len(weekends)

我修正的一些小问题:

  • 直接在列表中获取month_abbr,而不是在末尾添加两次
  • -1本身是有效索引
  • 两个工作日检查都是多余的

python正则表达式及使用正则表达式的例子

python正则表达式及使用正则表达式的例子

正则表达式

正则表达用来匹配字符串

正则表达式匹配过程

  1. 依次拿出表达式和文本中的字符串进行比价
  2. 如果每个字符都能匹配,则匹配成功;一旦有匹配不成功的字符,则匹配失败
  3. 如果有量词和边界,则匹配过程稍微有些不同

正则表达式语法规则

语法

说明

表达式实例

匹配字符串

字符

. 匹配除换行"\n"外的任意字符串 abc abc
\ 转义字符,使后一个字符改变原来的意思 a\\c a\c
[...] 字符集,对应的位置可以是字符集中任意字符,字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。第一个字符如果是^则表示取反,如[^abc]表示不是abc中的其他字符。所有的特殊的字符在字符集中都失去其原有的特殊含义。在字符集中使用^、]或-,可以使用转义字符匹配它们 a[bcd]e

abe

ace

ade

预定义字符集

\d 数字:[0-9] a\dc a1c
\D 非数字:[^0-9] a\Dc \s 空白字符:[<空格>\t\r\n\f\v] a\sc a c
\S 非空白字符:[^\s] a\Sc \w 单词字符:[a-zA-z0-9_] a\wc \W 非单词字符:[^\w] a\Wc a c

数量词

* 匹配一个字符串0或无限次 abc*

ab

abc

abccc

+ 匹配一个字符串1次或无限次 abc+

abc

abccc

? 匹配一个字符串0次或1次

abc?

ab

abc

{m} 匹配一个字符串m次 abc{2} abcc
{m,n} 匹配一个字符串m到n次 abc{2,3}

abcc

abccc

边界匹配

^ 匹配字符串开头 ^abc $ 匹配字符串末尾 abc$ \A 匹配字符串开始 \Aabc \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 abc\Z \b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

逻辑分组

| 匹配|表达式左右的任意一个 abc|def

abc

def

(...) 作为分组,每遇到一个(,分组编号加1,使用分组的好处是匹配的子串会保存到一个子组,便于以后使用 (abc){2} abcabc
(?P<name>...) 分组除原有编号外,再加一个别名 (?P<id>abc){2} \<number> 引用编号为number的分组匹配到的字符串 (\d)ab\1

1ab1

5ab5

(?P=name) 应用别名为name的分组匹配到的字符串 (?P<id>abc)ee(?P=name) abceeabc

特殊构造(不分组)

(?:...) (...)的不分组版本,用于|或后接数量词 (?:abc){2} (?iLmsux) iLmsux中的每个字符代表正则表达式的一种匹配模式,只能用在正则表达式开头,可选多个 (?i)abc AbC
(?#...) 将#后面的字符当做注释忽略 abc(?#comment)def abcdef
(?=...) 之后的字符串表达式需要匹配才能成功,不消耗字符串内容 a(?=\d) 后面是数字的a
(?!...) 之后的字符串表达式需要不匹配才能成功,不消耗字符串内容 a(?!\d) 后面不是数字的a
(?<=...) 之前的字符串表达式需要匹配才能成功,不消耗字符串内容 (?<=\d)a

前面是数字的a

(?<!...) 之前的字符串表达式需要不匹配才能成功,不消耗字符串内容 (?<!\d)a 前面不是数字的a

(?(id/name)yes_

pattern|no_parttern)

如果匹配到分组为id或别名name的字符串成功匹配,则需要匹配yes_pattern

不成功,怎需要匹配no_pattern

(\d)abc(?(1)\d|def)

1abc3

abcdef

贪婪模式和非贪婪模式

贪婪模式是尽可能多的匹配字符串,python默认为贪婪模式,非贪婪模式尽可能少的匹配字符串,在正则表达式后面加个?表示非贪婪模式。例如:字符串abcccb,贪婪模式正则表达式为ab.*c,非贪婪模式的正则表达式为ab.*?c,贪婪模式结果为abccc,非贪婪模式结果为abc,再比如字符串abbb,贪婪模式正则表达式为ab?,非贪婪模式正则表达为ab??,贪婪模式结果为ab,非贪婪结果为a。

python的re模块

re模块的方法:

1.compile(pattern[,flag]):对正则表达式pattern进行编译,编译后比直接查找速度快

2.match(patter,string[,flag]):从字符串string的开始就匹配,若匹配成功,则返回匹配对象,否则返回None(None对象没有group()和groups()方法,不判断直接调用这两个方法,则会出现异常)

3.search(pattern,flag]):从字符串中查找,若匹配成功,则返回匹配对象,否则返回None

4.findall(pattern,flag]):在字符串 string 中查找正则表达式模式 pattern 的所有(非重复)出现;返回一个匹配对象的列表

5.finditer(pattern,flags])b 和 findall()相同,但返回的不是列表而是迭代器;对于每个匹配,该迭代器返回一个匹配对象

6.split(pattern,string,max=0) 根据正则表达式 pattern 中的分隔符把字符 string 分割为一个列表,返回成功匹配的列表,最多分割 max 次(默认是分割所有匹配的地方)

7.sub(pattern,repl,max=0) 把字符串 string 中所有匹配正则表达式 pattern 的地方替换成字符串 repl,如果 max 的值没有给出, 则对所有匹配的地方进行替换

匹配对象的方法和属性:

  1. string:匹配时所使用的文本
  2. re:匹配时使用的pattern对象
  3. group(num=0) 返回全部匹配对象(或指定编号是 num 的子组)
  4. groups() 返回一个包含全部匹配的子组的元组(如果没有成功匹配,就返回一个空元组)

参数flag:

re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w,\W,\b,\B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

python使用正则表达式的例子

>>> import re
>>> pattern = re.compile(r'foo')
>>> res1 = re.search(pattern,'foo')
>>> res1.group() # 返回的是匹配对象,需要调用group()方法,显示所有的匹配对象
'foo'
>>> res1.groups()# 因为没有子组(即正则表达式中没有分组),返回空元组
()
>>> res2 = re.findall(pattern,'foobbfoo')
>>> res2 # 直接返回的是一个列表,包含所有匹配的字符
['foo','foo']
>>> pattern2 = re.compile(r'(\d+)aa')
>>> res3 = re.search(pattern2,'bb32aa')
>>> res3.group() # 返回所有的匹配的对象
'32aa'
>>> res3.groups() # 对比res1的groups(),正则里有分组,返回匹配到的分组
('32',)
>>> res4 = re.findall(pattern2,'bb32aacc5aacc')
>>> res4 # 对比res2,返回一个列表,但只包含所匹配分组里面的字符,
['32','5']

总结

以上所述是小编给大家介绍的python正则表达式及使用正则表达式的例子,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

您可能感兴趣的文章:

  • python爬虫 正则表达式使用技巧及爬取个人博客的实例讲解
  • Python使用正则表达式抓取网页图片的方法示例
  • Python正则表达式教程之三:贪婪/非贪婪特性
  • Python正则表达式教程之二:捕获篇
  • Python使用中文正则表达式匹配指定中文字符串的方法示例
  • python使用正则表达式匹配字符串开头并打印示例
  • Python正则表达式实现截取成对括号的方法
  • python利用正则表达式提取字符串
  • python 根据正则表达式提取指定的内容实例详解

可以在python的列表理解中使用多个条件吗?

可以在python的列表理解中使用多个条件吗?

self.instances_list = [
    {"Name": tag["Value"],"id": instance.id,"ip": instance.public_ip_address}
    for instance in self.get_all_instances
    for tag in instance.tags
    if tag.get("Key") == "Name" and "[Dev]" in tag["Value"]
]

今天关于如何在Python的列表理解中使用正则表达式?的讲解已经结束,谢谢您的阅读,如果想了解更多关于Python中使用正则表达式、Python如何在带条件的列表理解中使用多个for循环、python正则表达式及使用正则表达式的例子、可以在python的列表理解中使用多个条件吗?的相关知识,请在本站搜索。

本文标签: