You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用re.search筛选CSV含关键词行丢失数据的技术求助

问题排查与代码修正

我帮你梳理下代码里的几个核心问题,这应该就是导致符合条件的行没被写入新文件的关键原因:


1. 行号对应关系完全混乱

你第一个循环里用next(csvreader)跳过了表头,所以enumerate(csvreader)返回的line是从0开始,对应原文件的第2行(索引1);但第二个循环里你从头读取整个文件,idx从0开始对应原文件的表头(索引0),还加了idx+=-1的操作,这会让idx变成-1、0、1...完全和之前记录的healthy_new里的行号对不上!比如第一个循环里匹配到的line=0是原文件的第1行(数据行第一行),但第二个循环里idx要等于1才对应这行,可你把idx减了1,自然匹配不到。

2. 不必要的异常捕获

ValueError在这里根本不会触发,re.search只会在正则表达式格式错误时报错,而你的关键词都是普通字符串,这个try-except不仅多余,还可能掩盖真正的错误(比如row[4]不存在导致的索引越界)。

3. 文件打开模式错误

在Python 3中处理CSV文件,应该用文本模式('r'/'w')而不是二进制模式('rb'),二进制模式可能会导致读取的内容编码异常,直接影响关键词匹配结果。

4. 冗余匹配影响效率

你的healthy_list里有重复的'diet',而且匹配到关键词后还继续循环其他关键词,既浪费性能又会重复添加行号(虽然最后转成集合去重,但完全没必要)。


修正后的代码

我直接重构了逻辑,避免行号匹配的问题,同时优化了匹配效率:

import csv
import re

# 先给关键词列表去重,避免重复匹配
healthy_list = list(set(['diet', 'low-fat', 'light', 'diet', 'salad', 'salads', 'baked', 'grilled', 'whole grain']))
# 预编译正则表达式,用|分隔关键词,自动忽略大小写,不用手动转lower()
pattern = re.compile('|'.join(re.escape(word) for word in healthy_list), re.IGNORECASE)

healthy_rows = []

# 用文本模式打开,指定newline=''避免换行符混乱,编码按需调整
with open("Data 2017.csv", "r", newline='', encoding='utf-8') as f:
    csvreader = csv.reader(f, delimiter=",")
    # 先保存表头,写入新文件时需要
    header = next(csvreader)
    healthy_rows.append(header)
    
    # 直接遍历每一行,匹配到就加入结果列表,不用记录行号
    for row in csvreader:
        # 先检查列数足够,避免索引越界
        if len(row) >= 5:
            # 用预编译的正则快速匹配
            if pattern.search(row[4]):
                healthy_rows.append(row)

# 写入新文件,同样注意newline参数
with open("healthy_new_output.csv", "w", newline='', encoding='utf-8') as f:
    writer = csv.writer(f, delimiter=',')
    writer.writerows(healthy_rows)

关键改进点

  • 直接保存符合条件的行,彻底规避行号对应错误的问题
  • 预编译正则表达式,匹配效率更高,且自动忽略大小写
  • 先检查行的列数,避免索引越界报错
  • 用with语句管理文件,自动关闭资源,避免泄漏
  • 关键词列表去重,减少冗余匹配

内容的提问来源于stack exchange,提问作者sayalmondbutter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:08:18