Python实现CSV单个单元格拆分:分离题干与备选答案
高效拆分CSV中混合题干与选项的单元格内容
嗨,这个需求太常见了,处理这种把题干和选项揉在同一单元格的文本时,正则表达式是核心解决方案,再结合合适的工具就能高效搞定。我给你分几种场景推荐实用方案:
一、非编程用户:用Excel/Google Sheets公式快速处理
如果你不想写代码,用表格工具的内置函数就能轻松完成:
提取题干
用正则提取函数(Excel 365/Google Sheets均支持),精准匹配到第一个「数字+括号」之前的内容:
=REGEXEXTRACT(A1, "^.*?(?=\d+\))")
解释:^.*?(?=\d+\))是非贪婪匹配,会刚好停在第一个类似1)、2)的位置前,把前面的题干完整抓出来。
提取独立选项
先剥离题干,再按「数字+括号」拆分内容,最后过滤掉空值:
# Google Sheets 版本 =FILTER(SPLIT(REGEXREPLACE(A1, "^.*?(?=\d+\))", ""), "\d+\)"), SPLIT(REGEXREPLACE(A1, "^.*?(?=\d+\))", ""), "\d+\)")<>"") # Excel 365 版本 =FILTER(TEXTSPLIT(REGEXREPLACE(A1, "^.*?(?=\d+\))", ""), "\d+\)"), TEXTSPLIT(REGEXREPLACE(A1, "^.*?(?=\d+\))", ""), "\d+\)")<>"")
如果想清理选项里的无关前缀(比如示例里的OK),再加一层正则替换即可:
=ARRAYFORMULA(TRIM(REGEXREPLACE(FILTER(SPLIT(REGEXREPLACE(A1, "^.*?(?=\d+\))", ""), "\d+\)"), SPLIT(REGEXREPLACE(A1, "^.*?(?=\d+\))", ""), "\d+\)")<>""), "^[^a-zA-Z\u4e00-\u9fa5]+", "")))
二、编程用户:用Python批量处理CSV
如果你的CSV文件量大,或者需要自动化流程,用Python+pandas是最优解:
完整代码示例
import pandas as pd import re def split_question_and_options(text): # 提取题干:匹配到第一个「数字+括号」前的内容 question_match = re.match(r'^(.*?)(?=\d+\))', text) question = question_match.group(1).strip() if question_match else text # 提取所有选项:捕获「数字+括号」后的内容,直到下一个选项或文本结束 options = re.findall(r'\d+\)\s*(.*?)(?=\s*\d+\)|$)', text) # 清理选项里的无关前缀(比如示例里的"OK") cleaned_options = [re.sub(r'^[^a-zA-Z0-9\u4e00-\u9fa5]+', '', opt).strip() for opt in options] return question, cleaned_options # 读取CSV文件(假设只有一列,无表头) df = pd.read_csv("your_input.csv", header=None, names=["original_content"]) # 拆分题干和选项,生成新列 df[["question", "options"]] = df["original_content"].apply( lambda x: pd.Series(split_question_and_options(x)) ) # 可选:把选项拆成单独的列(比如option1, option2...) max_options = df["options"].apply(len).max() for i in range(max_options): df[f"option_{i+1}"] = df["options"].apply(lambda x: x[i] if i < len(x) else "") # 保存结果到新CSV df.to_csv("split_result.csv", index=False)
代码说明
- 正则
^(.*?)(?=\d+\))确保精准截取题干,不会误吞内容; \d+\)\s*(.*?)(?=\s*\d+\)|$)能正确捕获每个选项,哪怕选项之间没有空格;- 额外的清理步骤会自动去掉选项开头的无关字符(比如示例里的
OK)。
三、核心正则逻辑(通用所有工具)
不管你用Power Query、R语言还是其他工具,都可以基于这两个正则实现拆分:
- 题干匹配:
^.*?(?=\d+\))(匹配到第一个数字括号前的所有内容) - 选项匹配:
\d+\)\s*(.*?)(?=\s*\d+\)|$)(捕获每个选项的内容)
内容的提问来源于stack exchange,提问作者Mbaps
相关产品推荐
相关产品推荐

