使用正则表达式Python搜索和捕获角色

时间:2010-11-15 16:06:29

标签: python regex search text-files

在解决Python Challenge中的一个问题时,我试图按如下方式解决:

使用以下字符读取文本文件中的输入:

DQheAbsaMLjTmAOKmNsLziVMenFxQdATQIjItwtyCHyeMwQTNxbbLXWZnGmDqHhXnLHfEyvzxMhSXzd
BEBaxeaPgQPttvqRvxHPEOUtIsttPDeeuGFgmDkKQcEYjuSuiGROGfYpzkQgvcCDBKrcYwHFlvPzDMEk
MyuPxvGtgSvWgrybKOnbEGhqHUXHhnyjFwSfTfaiWtAOMBZEScsOSumwPssjCPlLbLsPIGffDLpZzMKz
jarrjufhgxdrzywWosrblPRasvRUpZLaUbtDHGZQtvZOvHeVSTBHpitDllUljVvWrwvhpnVzeWVYhMPs
kMVcdeHzFZxTWocGvaKhhcnozRSbWsIEhpeNfJaRjLwWCvKfTLhuVsJczIYFPCyrOJxOPkXhVuCqCUgE
luwLBCmqPwDvUPuBRrJZhfEXHXSBvljqJVVfEGRUWRSHPeKUJCpMpIsrV.......

我需要的是浏览这个文本文件,然后选择每边只有三个大写字母包围的所有小写字母。

我编写的用于执行上述操作的python脚本如下:

import re

pattern = re.compile("[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]")
f = open('/Users/Dev/Sometext.txt','r')
for line in f:
    result = pattern.search(line)
    if result:
       print result.groups()

 f.close()

上面给出的脚本,而不是返回捕获(小写字符列表),返回符合正则表达式条件的所有文本块,如

aXCSdFGHj
vCDFeTYHa
nHJUiKJHo
.........
.........

有人可以告诉我这里究竟出错了吗?而不是循环遍历整个文件,是否有另一种方法可以在整个文件上运行正则表达式搜索?

由于

3 个答案:

答案 0 :(得分:2)

我建议使用环视:

(?<=[A-Z]{3})(?<![A-Z].{3})([a-z])(?=[A-Z]{3})(?!.{3}[A-Z])

重叠匹配没有问题。

<强>解释

(?<=[A-Z]{3})  # assert that there are 3 uppercase letters before the current position
(?<![A-Z].{3}) # assert that there is no uppercase letter 4 characters before the current position
([a-z])        # match a lowercase character (all characters in the example are ASCII)
(?=[A-Z]{3})   # assert that there are 3 uppercase letter after the current position
(?!.{3}[A-Z])  # assert that there is no uppercase letter 4 characters after the current position

答案 1 :(得分:2)

result.groups()更改为result.group(1),您将获得单个字母匹配。

您的代码的第二个问题是它不会在一行中找到多个结果。因此,您需要使用re.searchre.findall,而不是re.finditerfindall将返回字符串或字符串元组,而finditer将返回匹配对象。

这是我遇到同样问题的地方:

import urllib
import re    

pat = re.compile('[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]')
print ''.join(pat.findall(urllib.urlopen(
    "http://www.pythonchallenge.com/pc/def/equality.html").read())) 

请注意,re.findallre.finditer会返回非重叠结果。因此,当使用上述模式并re.findall搜索字符串'aBBBcDDDeFFFg'时,您的唯一匹配将是'c',而不是'e'。幸运的是,这个Python Challenge问题不包含这样的例子。

答案 2 :(得分:1)

import re

with open('/Users/Dev/Sometext.txt','r') as f: 
    tokens = re.findall(r'[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]', f.read())

    for token ins tokens:
        print token

findall做了什么:

  

返回所有非重叠的匹配项   字符串中的模式,作为列表   字符串。扫描字符串   从左到右,比赛是   按顺序返回。如果一个或   更多的团体出现在   模式,返回组列表;这个   将是一个元组列表,如果   模式有多个组。空   匹配包含在结果中   除非他们触及开头   另一场比赛。

可能是re模块中最有用的功能。

read()函数将整个文件读入大字符串。如果您需要将正则表达式与整个文件匹配,这将非常有用。

警告:根据文件的大小,您可能更喜欢在第一种方法中逐行遍历文件。