正则表达式,以确保组匹配不以特定字符结尾
我遇到了一个正则表达式匹配特定情况的麻烦。我有电视的列表显示了在约4格式:正则表达式,以确保组匹配不以特定字符结尾
- Name.Of.Show.S01E01
- Name.Of.Show.0101
- Name.Of.Show.01x01
- 名称。 Of.Show.101
我想匹配的是显示名称。我的主要问题是,我的正则表达式匹配节目的名称与前面的'。'。我正则表达式如下:
"^([0-9a-zA-Z\.]+)(S[0-9]{2}E[0-9]{2}|[0-9]{4}|[0-9]{2}x[0-9]{2}|[0-9]{3})"
一些例子:
>>> import re
>>> SHOW_INFO = re.compile("^([0-9a-zA-Z\.]+)(S[0-9]{2}E[0-9]{2}|[0-9]{4}|[0-9]{2}x[0-9]{2}|[0-9]{3})")
>>> match = SHOW_INFO.match("Name.Of.Show.S01E01")
>>> match.groups()
('Name.Of.Show.', 'S01E01')
>>> match = SHOW_INFO.match("Name.Of.Show.0101")
>>> match.groups()
('Name.Of.Show.0', '101')
>>> match = SHOW_INFO.match("Name.Of.Show.01x01")
>>> match.groups()
('Name.Of.Show.', '01x01')
>>> match = SHOW_INFO.match("Name.Of.Show.101")
>>> match.groups()
('Name.Of.Show.', '101')
所以,问题是我该如何避免与期结束第一组?我意识到我可以简单地做到:
var.strip(".")
但是,这并不处理“Name.Of.Show.0101”的情况。有没有办法改进正则表达式来更好地处理这种情况?
在此先感谢。
我认为这会做:
>>> regex = re.compile(r'^([0-9a-z.]+)\.(S[0-9]{2}E[0-9]{2}|[0-9]{3,4}|[0-9]{2}x[0-9]{2})$', re.I)
>>> regex.match('Name.Of.Show.01x01').groups()
('Name.Of.Show', '01x01')
>>> regex.match('Name.Of.Show.101').groups()
('Name.Of.Show', '101')
ETA:当然,如果你只是试图从受信任的字符串不同的位,你可以只使用字符串方法:
>>> 'Name.Of.Show.101'.rpartition('.')
('Name.Of.Show', '.', '101')
因此,最后一组的唯一真正限制是它不包含点?简单:
^(.*?)(\.[^.]+)$
这匹配任何东西,非贪婪。重要的部分是第二组,它以一个点开始,然后匹配任何非点字符直到字符串结束。
这适用于所有的测试用例。
谢谢,这看起来不错,很好,简洁。 – 2010-05-19 18:15:58
如果最后一部分从不包含点:^(.*)\.([^\.]+)$
我相信这会做你想做的事:
^([0-9a-z\.]+)\.(?:S[0-9]{2}E[0-9]{2}|[0-9]{3,4}|[0-9]{2}(?:x[0-9]+)?)$
我测试此针对节目的以下列表:
- 30.Rock.S01E01
- The.Office.0101
- Lost.01x01
- How.I.Met .Your.Mother.101
如果这4种情况代表你所拥有的文件类型,那么这个正则表达式sho我们把节目名称放在自己的捕捉组中,然后扔掉剩下的节目。这个过滤器可能比其他一些更具限制性,但我非常喜欢匹配你需要的东西。
看来问题在于你没有指定需要最后一个组之前的时间段,所以像^([0-9a-zA-Z \。] +)\。(S [0 -9] {2} E [0-9] {2} | [0-9] {4} | [0-9] {2} X [0-9] {2} | [0-9] {3- })可能工作。
谢谢,它甚至从未将我的想法包括在内。在两组之外。我没有显示整个字符串,在剧集#之后通常还有其他一些项目,比如“The.Name.Of.Show.S01E01.something.else”,所以rpartition不起作用。 – 2010-05-19 18:11:24
@AJ:那么你应该小心,不要将'$'包含到正则表达式中 – SilentGhost 2010-05-19 18:13:09