在解决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
.........
.........
有人可以告诉我这里究竟出错了吗?而不是循环遍历整个文件,是否有另一种方法可以在整个文件上运行正则表达式搜索?
由于
答案 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.search
或re.findall
,而不是re.finditer
。 findall
将返回字符串或字符串元组,而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.findall
和re.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()函数将整个文件读入大字符串。如果您需要将正则表达式与整个文件匹配,这将非常有用。
警告:根据文件的大小,您可能更喜欢在第一种方法中逐行遍历文件。