0

我只是在学习 python 并且在弄清楚如何为以下字符串创建正则表达式模式时遇到问题

"...', 'begin:32,12:1:2005-10-30 T 10:45:end', 'begin:33,13:2:2006-11-31 T 11:46:end', '... <div dir="ltr">begin:32,12:1:2005-10-30 T 10:45:end<br>begin:33,13:2:2006-11-31 T 11:46:end<br>..."

我正在尝试提取 begin: 和 :end 之间的数据进行 n 次迭代,而不会获得重复的数据。我附上了我目前的尝试。

    for m in re.finditer('.begin:(.*),(.*):(.*):(.*:.*):end.', list_to_string(j), re.DOTALL):
    print m.group(1)
    print m.group(2)
    print m.group(3)
    print m.group(4)

输出是:

begin:32,12:1:2005-10-30 T 10:45:end<br>begin:33
13
2
2006-11-31 T 11:46

我希望它是:

32
12
1
2005-10-30 T 10:45
33
13
2
2006-11-31 T 11:46

感谢您的任何帮助。

4

3 回答 3

2

.*贪婪的,匹配你的预期:end边界。将所有.*s替换为lazy .*?

>>> s = """...', 'begin:32,12:1:2005-10-30 T 10:45:end', 'begin:33,13:2:2006-11-31 T 11:46:end', '... <div dir="ltr">begin:32,12:1:2005-10-30 T 10:45:end<br>begin:33,13:2:2006-11-31 T 11:46:end<br>..."""
>>> re.findall("begin:(.*?),(.*?):(.*?):(.*?:.*?):end", s)
[('32', '12', '1', '2005-10-30 T 10:45'), ('33', '13', '2', '2006-11-31 T 11:46'), 
 ('32', '12', '1', '2005-10-30 T 10:45'), ('33', '13', '2', '2006-11-31 T 11:46')]

使用修改后的模式,强制单引号出现在匹配的开始/结束处:

>>> re.findall("'begin:(.*?),(.*?):(.*?):(.*?:.*?):end'", s)
[('32', '12', '1', '2005-10-30 T 10:45'), ('33', '13', '2', '2006-11-31 T 11:46')]
于 2013-09-22T20:44:13.943 回答
0

您需要使模式的可变大小部分“非贪婪”。也就是说,使它们匹配尽可能小的字符串,而不是尽可能长的字符串(这是默认值)。

尝试模式'.begin:(.*?),(.*?):(.*?):(.*?:.*?):end.'

于 2013-09-22T20:47:05.523 回答
0

Blckknght 和 Tim Pietzcker 的另一个选择是

re.findall("begin:([^,]*),([^:]*):([^:]*):([^:]*:[^:]*):end", s)

不是选择非贪婪扩展,而是对某些 X[^X]表示“除 X 之外的任何字符”。

优点是它更严格:没有办法在结果中获取分隔符,所以

'begin:33,13:134:2:2006-11-31 T 11:46:end'

不会匹配,而对于 Blckknght 和 Tim Pietzcker 的则匹配。出于这个原因,它在边缘情况下也可能更快。这在现实世界中可能并不重要。

当然,缺点是它更加僵硬。

我建议选择更直观的方法,因为这两种方法都有效。

于 2013-09-22T21:10:07.077 回答