2014-01-31 231 views
2

我有以下Python代码会试图读取输入文件并找到给正则表达式的下列情况:正则表达式的Python

[fF][eE][bB]([1-2][0-9]|[0-9] 

我写了下面的Python代码

#!/usr/bin/python 
import re 
import sys 

textFile = open(sys.argv[1], 'r') 
fileText = textFile.read() 
textFile.close() 
matches = re.findall("[fF][eE][bB] ([1-2][0-9]|[0-9])",fileText) 
print matches 

和我的输入文件是:

1 2 3 the 
the quick 2354 
feb 1 
feb 0 
feb -10 
feb23 
feb 29 
feb 3 
february 10 

然而,当我跑我的代码我获得以下输出:['1','29', '3']

我希望我的输出更像['feb 1', 'feb 29', 'feb 3']

我真的不知道我在做什么错。任何帮助将不胜感激。

回答

1

为了使matches包含匹配的文本,您需要在整个表达式周围使用小括号。每对父亲会有一个比赛组;您可以使用(feb (?:[12][0-9]|[1-9]))进行分组而不捕获第二组。

但是,考虑到您的例子,或许您实际上想要在匹配时打印整个输入行?

+0

还应注意'1-9'避免匹配'二月文本0' 。如果你想匹配,表达式可以简化为'(feb [12]?[0-9])'。 – tripleee

+0

是的,'re.IGNORECASE'也是。 – tripleee

1

如果你想打印这个样子,

['feb 1', 'feb 29', 'feb 3'] 

您可以使用下面的代码,

matches = re.findall("(feb (?:[12][0-9]|[1-9]))",fileText) 
    print matches 
3

你应该read the documentation。当表达式中存在时,re.findall只返回捕获组。您应该简单地从你的正则表达式中删除捕获组:

matches = re.findall("[fF][eE][bB] (?:[1-2][0-9]|[0-9])",fileText) 
            ^^ 

这就是说,这个正则表达式也将匹配feb 0,所以你可能需要使用

[fF][eE][bB] (?:[1-2][0-9]|[1-9]) 
          ^

相反。

现在,如果您使用re.IGNORECASE(使正则表达式匹配大写和小写字符)以及如果使用循环读取文件内容(对于大文件更有效),则可以缩短正则表达式的时间。此外,这是一个很好的做法,原料您正则表达式模式:

with open(sys.argv[1], 'r') as textFile: 
    for line in textFile: 
     matches = re.match(r"feb (?:[1-2][0-9]|[1-9])", line, re.IGNORECASE) 
     if matches: 
      print matches.group() 

和当然,你可以把比赛中的列表太多,如果你需要在最后一个列表。

+0

+1真棒帖子,它包含了很多信息,其中大部分已经被我知道,但超过预期的信息未知。谢谢! – PascalVKooten

+0

@PascalvKooten不客气:) – Jerry

0

如何:

(feb\s[1-9][0-9]?) 

相配:二月后跟一个空格和0到9之间1和9,然后任何其它任选的数字之间的一个数字。

尝试:

matches = re.findall(r'(feb\s[1-9][0-9]?)',fileText) 
print matches 
>>> ['feb 1', 'feb 29', 'feb 3'] 

警告:这解决不了像 “二月51”

See it in action