在python中使用re group()返回None

时间:2018-04-30 13:39:40

标签: python regex

我使用的文本文件(itemsList)具有以下格式:

id "item 1"
str "item 1 description"

id "item 2"
str "item 2 description"

并试图用Python读取这个文件:

import re
itemList= open('itemsList.txt', encoding="utf8")
items=''
pattern = re.compile('(id\s)(\"(.*)\")|(str\s)(\"(.*)\")',re.IGNORECASE)
for item in itemList:
    Result = re.search(pattern,item)
    if Result:
        items+= Result.group(3)
    else:
        items+= "\n"

我收到了这个错误:

TypeError: must be str, not NoneType

Result.group(3)修改为str(Result.group(3)) 将此组给予该组:

item 1None
item 2None

预期结果应该是:

item 1, item 1 description
item 2, item 2 description

1 个答案:

答案 0 :(得分:0)

您的正则表达式使用|。因此,要么在前3组中匹配,要么在后3组中匹配。其他组值将返回None。因此,如果匹配idResult.group(3)将包含值,否则Result.group(6)将包含您的值:

import re

itemList= open('itemsList.txt', encoding="utf8")
items = ''

pattern = re.compile('(id\s)(\"(.*)\")|(str\s)(\"(.*)\")',re.IGNORECASE)

for item in itemList:
    Result = re.search(pattern,item)

    if Result:
        if Result.group(3):
            items += Result.group(3) + ','
        else:
            items += Result.group(6)
    else:
        items += "\n"        

print(items)        

这将打印以下内容:

item 1,item 1 description
item 2,item 2 description

另一种方法是避免使用正则表达式,而是将其视为CSV文件的特例。在这种情况下,空格字符将是分隔符,引号将自动视为单独的值。然后,您可以使用相同的库将行保存回新文件:

import csv

with open('input.txt', newline='', encoding='utf-8') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_input = csv.reader(f_input, delimiter=' ')
    csv_output = csv.writer(f_output)
    block = []

    for row in csv_input:
        if len(row):
            block.append(row)
        elif block:
            csv_output.writerow([block[0][1], block[1][1]])
            block = []

    if block:            
        csv_output.writerow([block[0][1], block[1][1]])

在你的代码中,你不断追加字符串来创建你的行。在Python中,这不是首选解决方案。最好将所有值附加到列表中,然后处理列表。

csv_output.writerow()获取行值列表,并在写入文件时自动添加必要的,和换行符。

我建议您添加print(row)print(block)以了解其工作原理。