正则表达式中的|符号似乎划分了整个模式,但我需要划分一个较小的模式…我希望它能找到一个以"Q: "开头的匹配。或者"A: ",然后在下一个"Q: "之前结束。或者"A:"。中间可以是任何字符,包括换行符。
我的尝试:
string = "Q: This is a question. nQ: This is a 2nd question non two lines. nnA: This is an answer. nA: This is a 2nd answer non two lines.nQ: Here's another question. nA: And another answer."
pattern = re.compile("(A: |Q: )[wW]*(A: |Q: |$)")
matches = pattern.finditer(string)
for match in matches:
print('-', match.group(0))
我使用的正则表达式是(A: |Q: )[wW]*(A: |Q: |$)
。
下面是多行相同字符串,仅供参考:
Q: This is a question.
Q: This is a 2nd question
on two lines.
A: This is an answer.
A: This is a 2nd answer
on two lines.
Q: Here's another question.
A: And another answer.
所以我希望括号会隔离开始的两个可能的模式和结束的三个可能的模式,但相反,它将其视为4个单独的模式。它也会在最后包括下一个A:或Q:但希望你能看到我想要什么。我本来打算不使用那个组的。
如果有帮助的话,这是一个简单的学习程序,它从文本文件中抓取问题和答案来测试用户。我可以让问题和答案各一行,但我很难得到一个"A"。或"Q: "有多行
一种方法是使用负正向?!
来匹配后跟A: | Q:
块的换行符,如下:
^([AQ]):(?:.|n(?![AQ]:))+
你也可以在这里的Regex Demo中尝试一下。
这是@Wiktor建议的另一种方法,应该更快一点:
^[AQ]:.*(?:n+(?![AQ]:).+)*
一个轻微的修改,我们匹配.*
而不是n+
(但注意,这也捕获了末尾的空行):
^[AQ]:.*(?:n(?![AQ]:).*)*
我建议使用for循环,因为至少对我来说更容易。回答你的问题,为什么不把目标锁定在这个时期而不是下一个时期呢?否则,你可能不得不使用查找头。
(A: |Q: )[sS]*?.
[sS]
(通常用于匹配每个字符,尽管[wW]
也可以)
*?
是一个延迟量词。它匹配尽可能少的字符。如果我们只有(A: |Q: )[sS]*?
,那么它只匹配(A: |Q: )
,但我们有结尾.
。
.
匹配文字句点。
For循环:
questions_and_answers = []
for line in string.splitlines():
if line.startswith(("Q: ", "A: ")):
questions_and_answers.append(line)
else:
questions_and_answers[-1] += line
# ['Q: This is a question. ', 'Q: This is a 2nd question on two lines. ', 'A: This is an answer. ', 'A: This is a 2nd answer on two lines.', "Q: Here's another question. ", 'A: And another answer.']```