如何在可选的多行文本中获得正确的匹配

How to get the correct matches in optional multiline text

我对 Regex 还很陌生,一直在尝试处理一些示例。

对于下面的这个例子,我得到了一个测试格式,我的 objective 是匹配每个问题和答案部分,然后为每个部分单独获取问题和属于该问题的所有答案。

以下是我一直在使用的正则表达式

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

我想在一天结束时实现的输出类似于

[
  {
    "question": "1. this is a question?",
    "answers": ["this is an answer", ...]
  },
  {
    "question": "2. this is a question?",
    "answers": ["this is an answer", ...]
  },
  {
    "question": "2. this is a multiline question?",
    "answers": ["this is a multiline answer", ...]
  }

]

目前我正在使用 Regex101.com 来处理这个例子。 下面是我匹配 Answer Regex 模式的屏幕截图。 当我只想每场比赛有 一个 答案时,我正在匹配多行。

我在使用 Answer Regex 模式时每次匹配的答案太多,我想知道如何在“问答”部分获得所有答案,但每个答案只有一个答案匹配。

我能得到一些帮助吗?谢谢!

此外,如果有更好的方法来完成任务,请告诉我。任何有关解析此测试格式的最正确方法的反馈都将不胜感激。

匹配问题使用

^\d+\.\s.*(?:\n(?!\s*[A-Z]).*)*

看到这个regex demo

答案可以匹配

^[A-Z]\.\s.*(?:\n(?!\s*(?:\d+|[A-Z])\.\s).*)*

参见 this regex demo

匹配整个段落可以用

^\d+\..*(?:\n.+)*

参见 this regex demo

我认为 this regex 太笨拙了,在这里不必要地冗长和复杂。

这是一个正则表达式的解释,它们非常相似:

  • ^ - 行首(确保使用 m 标志)
  • \d+ - 一位或多位数字
  • \. - 一个点
  • \s - 一个空格
  • .* - 一行的剩余部分
  • (?:\n(?!\s*[A-Z]).*)* - 零次或多次出现
    • \n(?!\s*[A-Z]) - 一个 LF 字符后跟零个或多个空格,然后是一个 ASCII 大写字母
    • .* - 该行的其余部分。