python - 使用正则表达式提取问题和答案
问题描述
我想从我正在阅读的一些文件中提取一些问题和答案,但我的正则表达式对我不起作用:
from re import findall,DOTALL
text='''
category 1
1. question
a) answer
b) answer
2. question
a) answer
b) answer
category 2
3. question
a) answer
b) answer
'''
文件中的格式基本上是一个编号列表,其中包含可变数量的索引答案,例如a)
b)
或a.
b.
...,答案在不同的地方跨越几行。我试过这个:
mo=findall(r"^\d\.(.+)(\w\)|\.(.+))+$",text,DOTALL)
print(mo)
我尝试放入捕获组以将问题与答案分开,删除"^"
给出了最接近的结果,但它仍然是垃圾,我不明白为什么会发生这种情况:
[(' question\na) answer\nb) answer\n2. question\na) answer\nb) answer\ncategory 2\n3', '. question\na) answer\nb) answer\n', ' question\na) answer\nb) answer\n')]
我正在考虑在答案之间寻找一个空格,以免将“类别”垃圾作为答案的一部分,或者更多地控制我的输入以支持没有空格的格式。
我正在尝试获得类似的输出(不需要是元组,这正是 findall 组返回的内容):
[('question', 'answer', 'answer'),
('question', 'answer', 'answer'),
('question', 'answer', 'answer')]
解决方案
我不会为多行需求编写怪物正则表达式,而是或多或少地使用正常的迭代和累积。您可以拆分/\n(?=[a-z\d][).] )/gm
以仅提取问答内容。遍历这些块,如果有问题,则开始一个新的问答块,否则附加到现有的块以累积结果。
import re
text = '''
category 1
1. q1
q1 foobar
a) a1.a
b) a1.b
some extra a1.b
2. q2
a) a2.a
b) a2.b
some extra a2.b
c) a2.c
blah a2.c
category 2
3. q3
a) a3.a
b) a3.b
extra a3.b
'''
qa = []
block = []
for chunk in re.split(r"\n(?=[a-z\d][).] )", text):
if m:= re.match(r"\d+\. (.+)", chunk, re.S):
qa.append(tuple(block))
block = [m.group(1)]
elif m := re.match(r"[a-z]+\) (.+?)(?=\n\n|$|[a-z]+\) )", chunk, re.S):
block.append(m.group(1))
qa = qa[1:] + [tuple(block)]
for line in qa:
print(line)
给出:
('q1\n q1 foobar', 'a1.a', 'a1.b\n some extra a1.b')
('q2', 'a2.a', 'a2.b\n some extra a2.b', 'a2.c\n blah a2.c')
('q3', 'a3.a', 'a3.b\nextra a3.b')
正则表达式解释:
/\n(?=[a-z\d][).] )/gs
在前瞻两个a)
或1.
模式的换行符上进行拆分。这使我们能够保留多行块。/\d+\. (.+)/gs
让我们识别一个1. question
块并捕获问题主体。/[a-z]+\) (.+?)(?=\n\n|$|[a-z]+\) )/gs
匹配a) answer
块。它与上面的块几乎相同1. question
,但它必须小心修剪下一个内容标题,它不是由上面的正则表达式 (1) 处理的。这就是(?=\n\n|$|[a-z]+\) )
前瞻的作用:如果以下是双换行符、字符串结尾或a)
,则不要将其包含在此答案中。
推荐阅读
- android - Android Staggered Grdiv 查看最后一个元素全屏(如果独立)
- scala - 在 Scala Spark 中将数据框列的值转换为数组
- android - Android 版本 29 和 27 中的应用启动器图标中未显示通知计数徽章
- javascript - 自定义 AsciiMath 数学分隔符
- triggers - dafny 如何应用触发器
- pandas - 在 matpplot 中增加 xy 值
- javascript - amcharts 堆积柱形图中的工具提示放置
- react-native - 错误:文本字符串必须在
组件,出现在 android 中,但在 web 上可以正常工作 - gitlab - Gitlab CI:在 Kaniko Job 中执行自己的脚本
- r - 根据年份找到加权平均值