2012-03-03 120 views
1

我想在字符串中找到一些非常特定的数据。问题是我没有找到我正在使用的当前正则表达式的所有数据。下面是一些示例数据:Python re.findall正则表达式问题

[img:2gcfa9cc]http://img823.imageshack.us/img823/3295/pokaijumonlogo.jpg[/img:2gcfa9cc] 

Making these little guys into Kaiju monsters. Again, I know nothing about them, other then which ones I thought would make for cool possible Kaiju (of the original 150) so here's Day 01 

[b:2gcfa9cc][size=150:2gcfa9cc]BULBASAUR[/size:2gcfa9cc][/b:2gcfa9cc] 
[i:2gcfa9cc]Feb 01[/i:2gcfa9cc] 
[ddf2k12:2gcfa9cc]http://img853.imageshack.us/img853/2185/dailydrawfeb2012day01.jpg[/ddf2k12:2gcfa9cc] 

Setting myself up with the same "parameters" as last year 

I may be breaking my own Challenge rules right now but...well I started this last night and I couldn't just leave 'em out in the cold all unfinished 'n' shit. 

Obligatory Skyrim drawing. 

[ddf2k12:2ytorpmj]http://4.bp.blogspot.com/-UIUSNXvnHz4/TynYf1BZ9oI/AAAAAAAAAl4/pRLHVP0Ny3U/s1600/01_cheatingcheaterwarmup1.jpg[/ddf2k12:2ytorpmj] 

我试图让是ddf2k12标签和标签img之间的数据。我到目前为止只在ddf2k12标签上工作过(我认为后者将是img而不是ddf2k12),而在我应该找到的1586个标签中,我只得到5个。下面是我的正则表达式:

ddf2k12_regex = '(\[[ddf2k12]+\:[A-Za-z0-9]+\])(.*?)(\[[ddf2k12]+\:[A-Za-z0-9]+\])' 
ddf2k12_find = re.findall(ddf2k12_regex, post) 

很明显,我的正则表达式有些问题,但是在将我的头撞到墙上之后,我无法将其整理出来,所以我们不胜感激。谢谢。

回答

3

你会通过将这个大的正则表达式分解成多个部分并使用合成来为你自己一个大忙。这似乎工作正常,更明显的是如何调试它。

import re 

start_tag = '(\[{tagname}:[^\]]+\])' 
end_tag = start_tag.replace('\[', '\[\/', 1) 
content = '((?:.|\n)*?)' # The ?: indicates a non-capturing group.                        
tag = start_tag + content + end_tag 

ddf_tag=tag.format(tagname='ddf2k12') 

for match in re.findall(ddf_tag, post): 
    print match 
+0

好多了!不过,我仍然想知道点在新行上卡住了。 – tchrist 2012-03-03 18:50:10

+0

是的!非常感谢,完美运作。是的,让它更清晰明确是一个更好的举措。我更喜欢使用%s标签来连接字符串,但那是我做的唯一不同的事情。再次感谢! – 2012-03-03 19:13:51

+0

不客气。 25代表使它完全值得;) – bukzor 2012-03-03 20:19:44

0

这为我工作 -

post = "[the data you want to be searched for using regex]" 
ddf2k12_regex = re.compile(r"\[ddf2k12(?P<data>[\n.]*?)\[/ddf2k12") 
ddf2k12_find = ddf2k12_regex.findall(post) 
+0

我发现令人困惑的是,您不仅将**数据**用作变量名**,而且还将**用于指定组;选择不同的标识符会更好吗?另外,我想知道你是否想在那里使用'(?s)'或're.DOTALL',这样点就可以跨越换行符边界。 – tchrist 2012-03-03 18:37:34

2

两件事情。首先,您在关闭ddf2k12标记中缺少/

>>> ddf2k12_regex = '(\[[ddf2k12]+\:[A-Za-z0-9]+\])(.*?)(\[/[ddf2k12]+\:[A-Za-z0-9]+\])' 
>>> re.findall(ddf2k12_regex, post) 
[('[ddf2k12:2gcfa9cc]', 'http&#58;//img853&#46;imageshack&#46;us/img853/2185/dailydrawfeb2012day01&#46;jpg', '[/ddf2k12:2gcfa9cc]')] 

所以现在它的工作。但是您将ddf2k12字符放在括号内,这些字符将与任何具有字符1,2,d,fk的标签匹配。

>>> silly_s = '[dddd:a]a[/ffff:a]' 
>>> re.findall(ddf2k12_regex, silly_s) 
[('[dddd:a]', 'a', '[/ffff:a]')] 

所以,你需要匹配确切的标签,而不是;这样做,删除那些外括号:

>>> ddf2k12_regex = '(\[ddf2k12\:[A-Za-z0-9]+\])(.*?)(\[/ddf2k12\:[A-Za-z0-9]+\])' 
>>> re.findall(ddf2k12_regex, post) 
[('[ddf2k12:2gcfa9cc]', 'http&#58;//img853&#46;imageshack&#46;us/img853/2185/dailydrawfeb2012day01&#46;jpg', '[/ddf2k12:2gcfa9cc]')] 
>>> re.findall(ddf2k12_regex, silly_s) 
[] 
+0

另外,在这种情况下它并不重要,但不要忘记通过以下方式使您的正则表达式字符串[原始字符串](http://docs.python.org/library/re.html#raw-string-notation)给他们预先加上'r'。 – senderle 2012-03-03 18:25:40

+0

我想我想在'(?x)'模式的多行中看到'r'''''''字符串中有这样一个长模式,每个模块都有其自身的空白并且可能还有评论,以便更易于阅读和维护。当它们全部挤在一起时,我会感到有点幽闭恐惧症,冒着让读者发生标点冲击的风险。 – tchrist 2012-03-03 18:44:52

+0

这确实奏效,并感谢您的帮助。我之所以选择以前的答案是因为他们进一步分解了这个问题,虽然这不是我的问题的一部分,但它可以更容易地将它重用于img标签。虽然+1了。 – 2012-03-03 22:43:14

0

问题是,你正在使用字符集,你不应该。试试下面的正则表达式来代替:

pattern = r'\[ddf2k12:\w+?\](.*?)\[/ddf2k12:\w+?\]' 

\ W等效于[A-ZA-Z0-9_]

注意,\ w和点的,如在语义(*?) ,可以通过使用DOTALL,LOCALE和UNICODE标志,或者通过向正则表达式添加(?s),(?L)或(?u)来改变。

+0

您是否认为您可能需要'(?s)'以便点可以跨越换行符边界?另外,'\ w'可以用'(?u)'包含Unicode,或者用'(?l)'包含locale。我现在几乎总是使用Unicode风格,并且不再使用它自己的区域风格。 – tchrist 2012-03-03 18:47:31

+0

@tchrist:这是一个很好的观点。我想你可能想这样做。 – 2012-03-03 19:10:18

0

分组文本在一起是(sometex),而不是[sometext]。我认为ddf2k12标签可能会出现在您的[...]一侧。将+关闭,您现在不需要(...)

\[ddf2k12:[a-zA-Z0-9]+\](.*?)\[/ddf2k12:[a-zA-Z0-9]+\] 

会做得很好。请注意,返回值是来自(.*?)的文本。如果你想获得标签名称,你可以使用(...)包装ddf2k12。然后与你的img标签组合的版本会是这样的。

\[(ddf2k12|img):[a-zA-Z0-9]+\](.*?)\[/(ddf2k12|img):[a-zA-Z0-9]+\] 
+0

是否应该有一个'(?s)'那里的点来匹配换行符?这可能是一个用'(?x)'使用多行匹配的好地方,这样你就可以包含注释。对于在正则表达式中重复出现的事情,我有点困扰:'(ddf2k12 | img)'和'[a-zA-Z0-9] +'会出现两次,这有可能会因为违反了DRY(“不要重复你自己”)规则。我认为你应该能够在这里使用命名组来使这个更加自我记录,并且从代码安全的角度来看更易于维护。 – tchrist 2012-03-03 18:42:08