1

我有一段重复多次的文本。在这里,您有该文本的示例:

文字的DEMO

这个想法是有一个包含三个组的正则表达式,并对任何匹配与文本重复此操作。这里有一个可能匹配的例子:

group1 = HORIZON-CL5-2021-D1-01
group2 (Opening) = 15 Apr 2021
group3 (Deadlines(s)) = 07 Sep 2021


group1 = HORIZON-CL5-2022-D1-01-two-stage
group2 (Opening) = 04 Nov 2021
group3 (Deadlines(s)) = 15 Feb 2022 (First Stage), 07 Sep 2022 (Second Stage)

我正在尝试使用这个正则表达式:

\n(HORIZON-\S+-[A-Z]{1}\d{1}-\d{2}).*?^Opening

它几乎可以工作。我需要在正则表达式中多说两件事:

  1. 在某些情况下,在最后一个 HORIZON... 之后可能会出现一些文本,例如第二种情况:

HORIZON-CL5-2022-D1-01-两级

  1. 我需要说“抓住一切”,直到“Opening:”这个词出现在一行的开头。我以为是用这部分表达式来做这件事, .*?^Opening但似乎不正确。

我该如何解决这个问题?

4

3 回答 3

2

要获得第-two-stage1 组,您可以将匹配的 0+ 个非空白字符添加\S*到现有组。

您不需要s修饰符来使点匹配换行符。相反,您可以使用负前瞻匹配所有不以Opening 开头的行,然后匹配Opening并在捕获组中捕获日期和截止日期部分。

请注意,您可以省略{1}

^(HORIZON-\S+-[A-Z]\d-\d{2}\S*)(?:\r?\n(?!Opening\b).*)*\r?\nOpening: (.+)\r?\nDeadline\(s\): (.+)

正则表达式演示

您可以根据需要使以日期开头的组为特定部分,.+广泛匹配也是如此。

例如

^(HORIZON-\S+-[A-Z]\d-\d{2}\S*)(?:\r?\n(?!Opening\b).*)*\r?\nOpening: (\d{2} [A-Z][a-z]{2} \d{4})\r?\nDeadline\(s\): (\d{2} [A-Z][a-z]{2} \d{4}.*)

正则表达式演示

于 2021-02-10T10:00:19.277 回答
1
  1. 在您的模式中,您在第一组中重复 HORIZON-... 例如HORIZON-()-A1-11HORIZON-+-B2-33,虽然这不应该出现在您的输入中,但它不应该是一个问题。

  2. 您的模式中需要开头,我会用积极的前瞻代替它(Opening|$),其中$表示行尾。

  3. 看来你没有对你正在检索的字符串部分做任何事情,从你的例子中我认为你可以简单地匹配非空格。

const pattern = /\n(HORIZON-\S+)\s*(.*?)\s*(?=Opening|$)/
  1. 如果您想保留原始模式并将其余文本捕获在一个单独的组中,那就是/\n(HORIZON-\S+-[A-Z]{1}\d{1}-\d{2})(\S*)\s*(.*?)\s*(?=Opening|$)/. 这

  2. 以 '\n' 开头的表达式与第一行不匹配,您可以将其更改为/^(HORIZON-\S+-[A-Z]{1}\d{1}-\d{2})(\S*)\s*(.*?)\s*(?=Opening|$)/.

于 2021-02-10T09:52:56.523 回答
0

你可以有这样的东西:HORIZON-\S+-[A-Z]{1}\d{1}-\d{2}(-[^\s]*)?. 我添加了(-[^\s]*)?部分。在这里,我告诉正则表达式匹配以找到-空格 ( \s) 开头的内容。这?使得这部分是可选的,因此它可以显示一次或根本不显示。

于 2021-02-10T09:33:00.697 回答