PHP:非格式化文本自定义解析器开发问题求助
修正PHP测验题解析函数,搞定随机换行与空格问题
我来帮你解决这个测验题解析的麻烦!你的核心问题在于原始文本里的随机换行、空格把题目和选项拆得七零八落,原代码按行处理的思路根本扛不住这种混乱格式——咱们换个正则匹配的思路,一步到位解决问题。
先说说原代码的问题
- 按换行分割文本:但题目和选项可能挤在同一行,或者选项跨了好几行,导致无法正确识别题目边界
- 用开头数字判断题目:如果题目文本里刚好开头有数字,就会直接误判成新题目
- 选项拆分逻辑太简单:没法处理多个选项在同一行的情况,很容易拆错
解决方案思路
- 先把文本“捋顺”:把所有换行、制表符、多空格都换成单个空格,消除格式干扰
- 用正则批量抓完整题目:直接匹配从一个题目编号到下一个题目编号(或文本结尾)的完整内容,确保每一道题都被完整捕获
- 拆分每个题目的选项:再用正则把每个选项的标识(a/e)和内容对应起来
修正后的完整代码
<?php // 原始文本(模拟带随机换行、空格的情况) $rawText = '1. 一辆汽车平均每加仑行驶27英里。若汽油每加仑4.04美元,该车行驶2727英里的汽油成本最接近以下哪个选项?a) $44.44 b) $109.08 c) $118.80 d) $408.04 e) $444.40 2. 当x=3、y=5时,3x²–2y的值比2x²–3y的值大多少?a) 4 b) 14 c) 16 d) 20 e) 50'; // 第一步:预处理文本,消除所有多余空白(换行、多空格、制表符都换成单个空格) $cleanText = preg_replace('/\s+/', ' ', trim($rawText)); // 第二步:正则匹配所有完整题目 // 正则说明: // \d+\. 匹配题目编号(数字+点) // (.*?) 非贪婪匹配题目文本,直到遇到a)开头的选项 // ((?:[a-e]\) .*? )*(?:[a-e]\) .*?)) 匹配所有a)到e)的选项 // (?: \d+\. |$) 匹配下一个题目的开头或者文本结尾,作为题目边界 $questionPattern = '/(\d+)\. (.*?) ((?:[a-e]\) .*? )*(?:[a-e]\) .*?))(?: \d+\. |$)/'; preg_match_all($questionPattern, $cleanText, $matches, PREG_SET_ORDER); $processedQuestions = []; foreach ($matches as $match) { $questionNumber = $match[1]; $questionText = trim($match[2]); $optionsStr = trim($match[3]); // 第三步:拆分每个选项 $optionPattern = '/([a-e])\) (.*?)(?= [a-e]\) |$)/'; preg_match_all($optionPattern, $optionsStr, $optionMatches, PREG_SET_ORDER); $options = []; foreach ($optionMatches as $opt) { $options[$opt[1]] = trim($opt[2]); } $processedQuestions[$questionNumber] = [ 'questionNumber' => $questionNumber, 'questionText' => $questionText, 'options' => $options ]; } // 输出验证结果 print_r($processedQuestions); ?>
输出的规范数组结构
运行代码后,你会得到完全符合预期的数组:
Array ( [1] => Array ( [questionNumber] => 1 [questionText] => 一辆汽车平均每加仑行驶27英里。若汽油每加仑4.04美元,该车行驶2727英里的汽油成本最接近以下哪个选项? [options] => Array ( [a] => $44.44 [b] => $109.08 [c] => $118.80 [d] => $408.04 [e] => $444.40 ) ) [2] => Array ( [questionNumber] => 2 [questionText] => 当x=3、y=5时,3x²–2y的值比2x²–3y的值大多少? [options] => Array ( [a] => 4 [b] => 14 [c] => 16 [d] => 20 [e] => 50 ) ) )
这个方案完全不怕原始文本里的随机换行、空格,而且适合批量处理2万道题的场景,效率也能满足需求。
内容的提问来源于stack exchange,提问作者user5281753
相关产品推荐
相关产品推荐

