0

我有一个巨大的文本文件(1 GB),其中每个“行”都符合语法:

[number] [number]_[number]

例如:

123 123_1234
45 456_45    12 12_12

我收到以下错误:

  line 46, in open_delimited
    pieces = re.findall(r"(\d+)\s+(\d+_\d+)", remainder + chunk, re.IGNORECASE)
TypeError: can only concatenate tuple (not "str") to tuple

在这段代码上:

def open_delimited(filename, args):
    with open(filename, args, encoding="UTF-16") as infile:
        chunksize = 10000
        remainder = ''
        for chunk in iter(lambda: infile.read(chunksize), ''):
            pieces = re.findall(r"(\d+)\s+(\d+_\d+)", remainder + chunk, re.IGNORECASE)
            for piece in pieces[:-1]:
                yield piece
            remainder = pieces[-1]
        if remainder:
            yield remainder

filename = 'data/AllData_2000001_3000000.txt'
for chunk in open_delimited(filename, 'r'): 
    print(chunk)   
4

2 回答 2

4

re.findall()当模式中给出多个捕获组时,返回一个元组序列。您的模式有两个这样的组。因此,每个piece都由(number, number_number)对组成:

>>> re.findall(r"(\d+)\s+(\d+_\d+)", '45 456_45    12 12_12')
[('45', '456_45'), ('12', '12_12')]

请注意,由于您只匹配空格和数字因此该re.IGNORECASE标志是完全多余的。

您将最后一个这样的分配pieceremainder,然后循环备份并将其添加到chunk,这不起作用:

>>> ('12', '12_12') + '123 123_1234\n'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "str") to tuple

也许您想再次将这些值重新加入一段有效的文本中:

remainder = '{} {} '.format(*pieces[-1])
于 2013-08-12T15:06:14.403 回答
1

如前所述,您的处理中有一个错误:findall()给出一个元组列表。

一种替代方法可能是

def open_delimited(filename, args):
    with open(filename, args, encoding="UTF-16") as infile:
        chunksize = 10000
        remainder = ''
        for chunk in iter(lambda: infile.read(chunksize), ''):
            remainder += chunk # add it to the to-be-processed string
            pieces = list(re.finditer(r"(\d+)\s+(\d+_\d+)", remainder, re.IGNORECASE))
            # Those pieces are match objects.
            for piece in pieces[:-1]: # omit the last one, as before
                yield piece.group() # the whole match
            remainder = remainder[pieces[-1].start()] # the last one tells us where to start again.
        if remainder:
            yield remainder

在这里,pieces它们不是字符串元组,而是匹配对象。它们不仅告诉我们它们包含什么,还告诉我们它们来自哪里。

这允许轻松“重新创建”“剩余”。

于 2013-08-12T15:35:00.160 回答