【问题标题】:How to read line and move on to the next line if the identifiers are not present?如果标识符不存在,如何读取行并转到下一行?
【发布时间】:2020-11-28 03:13:29
【问题描述】:

在下面的代码中,每当行没有三个标识符中的每一个时,我都会收到一个错误。如果文件中不存在标识符,如何跳过该行并移至下一行?如果第一行没有 mfgcode、modelno 和 qtyavail,则程序失败。感谢您的宝贵时间。

import csv
import re

with open('file.csv', 'r') as csv_file:
    csv_reader = csv.reader(csv_file)

ff = []
for line in csv_reader:
       ff.append([re.search('mfgcode="(.+?)"', line[0] ).group(1),re.search('modelno="(.+?)"', line[0] ).group(1),re.search('qtyavail="(.+?)"', line[0] ).group(1)])
        
df = pd.DataFrame(ff,columns =['mfgcode','modelno','qtyavail'])
df.to_csv("test.csv",index=False)
print (df)

追溯:

 line 10, in <module>
    ff.append([re.search('mfgcode="(.+?)"', line[0] ).group(1),re.search('modelno="(.+?)"', line[0] ).group(1),re.search('qtyavail="(.+?)"', line[0] ).group(1)])
AttributeError: 'NoneType' object has no attribute 'group'

csvfile 的前三行:

<checkresp>  <header errcode="success" errmsg="sucess" />
<part branch="1" core="0.00" cost="15.69" deliverytime="1" desc="" errcode="success" kit="" linecode="nike" linenum="1" list="23.42" mfgcode="nike" modelno="1221" qtyavail="120" qtyreq="1" uom="" />
</checkresp>

【问题讨论】:

  • 您能否发布所引发错误的完整回溯(终端输出)?这将帮助我们缩小问题所在。
  • 如果您还可以共享两行,那将非常有帮助 - 一个存在标识符,另一个不存在标识符。
  • @JoshHonig 我已更新以包含回溯。谢谢
  • @Harsh 我更新了帖子,包括 csv 的前三行。第一行和第三行没有标识符,但第二行有。谢谢

标签: python csv python-requests append re


【解决方案1】:

您正在尝试将以下内容插入到列表中:

[re.search('mfgcode="(.+?)"', line[0] ).group(1),re.search('modelno="(.+?)"', line[0] ).group(1),re.search('qtyavail="(.+?)"', line[0] ).group(1)]

问题是,当re.search 什么都没有找到时,它返回一个None 的对象。您正在尝试获取 re.search 结果的匹配组 1,但是当它什么也没找到时,它会引发异常,因为您无法获取 None 的组 1。

re.search 确实找到匹配项时,它会返回一个re.Match 类型的对象; this 是当您想要获得搜索的匹配组 1 时。请参见下面的示例。

>>> import re
>>> a = re.search('a', 'b')
>>> type(a)
<class 'NoneType'>
>>> a = re.search('a', 'a')
>>> type(a)
<class 're.Match'>
>>> 

将您的搜索语句移到数组之外以追加可能会有所帮助。像这样的:

ff = []
for line in csv_reader:
       mfgcode = re.search('mfgcode="(.+?)"', line[0] )
       modelno = re.search('modelno="(.+?)"', line[0] )
       qtyavail = re.search('qtyavail="(.+?)"', line[0] )
       ff.append(
              [
                     'No Data' if mfgcode is None else mfgcode.group(1),
                     'No Data' if modelno is None else modelno.group(1),
                     'No Data' if qtyavail is None else qtyavail.group(1),
              ]
       )

请注意,这使用了内联 if 语句,这在 here 中有很好的解释。

【讨论】:

    【解决方案2】:

    我认为南波的解决方案应该足够了。

    但是,如果您想在不使用 try-catch 的情况下执行此操作,请考虑是否存在其中一个标识符,那么其他标识符也存在,只搜索其中一个,如果搜索失败则继续 -

    mfgcode = re.search('mfgcode="(.+?)"', line[0])
    if mfgcode:
        ff.append([mfgcode.group(1),re.search('modelno="(.+?)"', line[0] ).group(1),re.search('qtyavail="(.+?)"', line[0] ).group(1)])
    

    我仍然担心的一件事是line[0]。确保它代表您需要的线。

    【讨论】:

    • 代替 ff.append 行。
    猜你喜欢
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    相关资源
    最近更新 更多