1

我有一个混合了大写和小写字母的字符串。我需要找到每个被 3 个大写字母包围的小写字母并将其从字符串中提取出来。

例如ZZZaZZZ,我想提取a上一个字符串中的。

我写了一个能够提取ZZZaZZZ但不是a单独的脚本。我知道我需要使用嵌套的正则表达式来执行此操作,但我无法完全了解如何实现这一点。以下是我所拥有的:

import string, re                                                                                                                                                                

if __name__ == "__main__":                                                                                                                                                       

    #open the file                                                                                                                                                               
    eqfile = open("string.txt")                                                                                                                                                
    gibberish = eqfile.read()                                                                                                                                                    
    eqfile.close()                                                                                                                                                               

    r = re.compile("[A-Z]{3}[a-z][A-Z]{3}")                                                                                                                                      
    print r.findall(gibberish)           

编辑: 谢谢你们的回答!我想我应该更具体一些。我需要找到被三个完全相同的大写字母包围的小写字母,例如在我的示例ZZZaZZZ中。

4

3 回答 3

5

你是如此接近!阅读MatchObjects.group的* 方法。例如,如果您的脚本以

r = re.compile("[A-Z]{3}([a-z])[A-Z]{3}")
print r.match(gibberish).group(1)

然后您将在第一组中捕获所需的字符。

为了解决匹配重复字母的新约束,您可以使用反向引用:

r = re.compile(r'([A-Z])\1{2}(?P<middle>[a-z])\1{3}')
m = r.match(gibberish)
if m is not None:
    print m.group('middle')

内容如下:

  1. 匹配一个字母 AZ 并记住它。
  2. 匹配两次出现的第一个字母。
  3. 匹配您的小写字母并将其存储在名为middle.
  4. 匹配找到的第一个字母的另外三个连续实例。
  5. 如果找到匹配项,则打印该middle组的值。
于 2012-05-03T00:05:10.833 回答
3
r = re.compile("(?<=[A-Z]{3})[a-z](?=[A-Z]{3})") 

(?<=...)表示积极的后视,(?=...)是积极的前瞻。

模块重新

(?=...)

匹配 if ... 匹配下一个,但不消耗任何字符串。这称为前瞻断言。例如,仅当它后面跟着. 时Isaac (?=Asimov)才会匹配。'Isaac ''Asimov'

(?<=...)

如果字符串中的当前位置前面有一个在当前位置结束的 ... 匹配,则匹配。

于 2012-05-03T00:03:47.537 回答
3

您需要使用括号捕获您感兴趣的字符串部分,然后使用以下命令访问它re.MatchObject#group

r = re.compile("[A-Z]{3}([a-z])[A-Z]{3}")                                                                                                                                      
m = r.match(gibberish)
if m:
   print "Match! Middle letter was " + m.group(1)           
else:
   print "No match."
于 2012-05-03T00:09:27.547 回答