如何验证大型CSV文件是否以反引号`作为分隔符?
验证CSV文件是否严格使用反引号`作为分隔符
嘿,我来帮你搞定这个CSV验证的问题!首先先提个容易忽略的小bug:你原代码里的循环遍历了所有文件,但每次打开的都是第一个文件self.fullcsvpathfiles[0],得改成csvfile才行,不然只会验证第一个文件,白忙活一场~
下面给你两个实用的验证方案,既然你说算力不成问题,大文件也完全不用担心:
方案一:简单快速验证(基于字段数匹配)
这个方案利用CSV解析后的字段数是否和表头一致来判断分隔符是否正确。如果某一行用了错误的分隔符(比如逗号、空格),解析出来的字段数肯定和表头不匹配,直接抛出错误。
import csv for csvfile in self.fullcsvpathfiles: print(f"Validating {csvfile}...") with open(csvfile, mode='r', newline='') as csv_file: # 读取表头,获取预期的字段数量 csv_reader = csv.DictReader(csv_file, delimiter="`") expected_field_count = len(csv_reader.fieldnames) # 重置文件指针到开头,用普通reader逐行检查 csv_file.seek(0) raw_reader = csv.reader(csv_file, delimiter="`") next(raw_reader) # 跳过表头行 line_number = 2 # 数据行从第2行开始计数 for row in raw_reader: if len(row) != expected_field_count: raise ValueError( f"Invalid line {line_number} in {csvfile}: " f"Expected {expected_field_count} fields, got {len(row)}. " "Check for incorrect delimiters or unquoted special characters." ) line_number += 1
为什么这个方法有效?
- 当CSV行使用了错误的分隔符时,
csv.reader会把错误的分隔符当成字段的一部分,导致解析出的字段数和表头不一致。 - 操作简单,不需要复杂的正则,适合大多数常规场景。
方案二:严格验证(检查原始行结构)
如果需要更严谨的验证(比如确保没有未闭合的引号、字段内的反引号被正确包裹),可以直接检查原始行的结构,确保所有的`要么是分隔符,要么被引号包裹在字段内部。
import re def is_valid_csv_line(line, delimiter='`'): # 正则表达式:匹配CSV行的合法结构,忽略引号内的分隔符 # 匹配规则:(分隔符或行首) + (带引号的字段内容或不带引号的字段内容) + (分隔符或行尾) pattern = re.compile( rf'(?:^|\{delimiter})(?:"([^"]*)"|([^{delimiter}]*))(?:$|\{delimiter})' ) # 去掉行尾的换行符 cleaned_line = line.rstrip('\n\r') # 检查引号是否成对(未闭合的引号会导致解析错误) if cleaned_line.count('"') % 2 != 0: return False # 匹配所有字段,合并捕获组(每个字段要么在引号里,要么不在) matches = pattern.findall(cleaned_line) fields = [match[0] or match[1] for match in matches] # 验证最后一个字段是否匹配行尾(避免行末有多余字符) if not cleaned_line.endswith(delimiter): last_field = fields[-1] if fields else '' if not cleaned_line.endswith(last_field): return False return True for csvfile in self.fullcsvpathfiles: print(f"Strictly validating {csvfile}...") with open(csvfile, mode='r') as csv_file: line_number = 1 for line in csv_file: if not is_valid_csv_line(line): raise ValueError( f"Invalid line {line_number} in {csvfile}: " "Incorrect delimiter usage or unclosed quotes detected." ) line_number += 1
这个方案的优势:
- 直接检查原始行,不会被CSV解析器的容错机制掩盖问题。
- 能检测出未闭合的引号、字段内未被包裹的分隔符等隐蔽问题。
内容的提问来源于stack exchange,提问作者OpenMeyends
相关产品推荐
相关产品推荐

