我遇到一个正则表达式以匹配特定情况时遇到问题。我有大约4种格式的电视节目清单:
我想要匹配的是节目名称。我的主要问题是我的正则表达式与节目的名称匹配前面的'。'。我的正则表达如下:
"^([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”的情况。有没有办法可以改进正则表达式来更好地处理这种情况?
提前致谢。
答案 0 :(得分:2)
所以对最后一组的唯一真正限制是它不包含点?易:
^(.*?)(\.[^.]+)$
这非常贪婪。重要的部分是第二组,以点开头,然后匹配任何非点字符,直到字符串结束。
这适用于所有测试用例。
答案 1 :(得分:2)
我认为这样做:
>>> 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')
答案 2 :(得分:1)
我相信这会做你想要的:
^([0-9a-z\.]+)\.(?:S[0-9]{2}E[0-9]{2}|[0-9]{3,4}|[0-9]{2}(?:x[0-9]+)?)$
我针对以下节目列表对此进行了测试:
如果这4个案例代表您拥有的文件类型,那么该正则表达式应该将节目标题放在其自己的捕获组中并丢弃其余的。这个过滤器可能比其他过滤器更具限制性,但我很喜欢完全匹配你需要的东西。
答案 3 :(得分:1)
似乎问题是你没有指定需要最后一组之前的时间段,所以像^([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} )可能会工作。
答案 4 :(得分:0)
如果最后一部分从不包含点:^(.*)\.([^\.]+)$