如何使用Regex正确匹配可选多行文本 实现试题题目与答案分段提取
正则调整方案与试题解析实现
现有正则问题
你当前使用的正则存在两个核心问题:
- 答案匹配规则中的
[^]会匹配任意字符包括换行符,会直接吞噬多行内容,无法按单个答案拆分 - 题目匹配规则仅支持单行题目,无法适配换行的多行题目场景
优化后正则方案
推荐使用「单题全量匹配+分组捕获」的方案,比分开匹配分段、题目、答案准确率更高,不会出现跨题匹配的问题:
- 整题匹配正则(开启
gm模式):/^(\d+\.[\s\S]+?\?)[\r\n]+((?:[A-Z]\.[\s\S]+?(?=[\r\n]+[A-Z]\.|[\r\n]{2,}|\s*$))+)/gm- 第一捕获组匹配完整题目:从数字加
.开头到问号结束,[\s\S]支持匹配换行,非贪婪模式适配多行题目 - 第二捕获组匹配当前题的所有答案集合,通过正向预查判断答案边界:下一个答案开头、两道题之间的空行、文本结束位置
- 第一捕获组匹配完整题目:从数字加
- 单答案匹配正则(针对上述第二捕获组的内容匹配,开启
g模式):/([A-Z])\.([\s\S]+?)(?=[\r\n]+[A-Z]\.|$)/g- 每个匹配结果对应一个答案,自动合并多行答案内容,匹配后仅需去除多余空格和换行即可
完整实现示例
以下为JavaScript实现代码,输出完全符合你要求的格式:
const examText = `1. this is a question? A. This is an answer B. This is an answer 2. this is a question? A. This is an answer B. This is an answer 3. this is a question multiline? A. This is an multiline answer B. This is an answer`; const questionRegex = /^(\d+\.[\s\S]+?\?)[\r\n]+((?:[A-Z]\.[\s\S]+?(?=[\r\n]+[A-Z]\.|[\r\n]{2,}|\s*$))+)/gm; const answerRegex = /([A-Z])\.([\s\S]+?)(?=[\r\n]+[A-Z]\.|$)/g; const result = []; let questionMatch; while ((questionMatch = questionRegex.exec(examText)) !== null) { // 格式化题目,去除多余换行和空格 const question = questionMatch[1].replace(/\s+/g, ' ').trim(); const answers = []; // 提取当前题的所有答案 let answerMatch; while ((answerMatch = answerRegex.exec(questionMatch[2])) !== null) { const answer = answerMatch[2].replace(/\s+/g, ' ').trim(); answers.push(answer); } result.push({ question, answers }); } console.log(JSON.stringify(result, null, 2));
内容的提问来源于stack exchange,提问作者Scrubster
相关产品推荐
相关产品推荐

