正则表达式匹配,直到下一场匹配

时间:2019-01-16 18:12:16

标签: regex pcre

我有一个包含代码和每个代码文本的文本,它遵循某种模式。我正在尝试通过将每个模式分组来获取代码和每个代码的文本,但是,我的模式匹配并返回1匹配项,并获得一组中的第一个代码,整个文本中的其余部分作为第二组。我要达到的目标是让我的第二组尽可能地匹配,直到看到重复的模式为止。我正在使用regex101来摆弄模式,并查看可以使用的模式,但有几个选项没有产生结果。

在我的模式中,我指定了代码应为([A-Z0-9]{1,6}),我还尝试按照以下说明指定将要使用的代码(ADD|DELETE),但似乎仍然可以匹配一次。

这可以实际完成吗,还是我的模式模糊不清,对我的情况无效?我正在处理的模式和文本包含在上面的链接中。

1 个答案:

答案 0 :(得分:0)

您要使用

(?s)\/([A-Za-z0-9]{1,6})\/((?:(?!\/[A-Za-z0-9]{1,6}\/).)*)

请参见regex demo

可以使用较短的版本,因为在PCRE中,您可以使用正则表达式子例程递归捕获组模式。 \/([A-Za-z0-9]{1,6})\/部分可以使用其自己的捕获组进行包装,然后,您可以使用(?1)

(?s)(\/([A-Za-z0-9]{1,6})\/)((?:(?!(?1)).)*)

请参见this regex demo。请注意,“技术”组#1的存在,它将始终出现在比赛结果中。

但是,如果您更喜欢效率,我宁愿推荐同一正则表达式的展开版本:

\/([A-Za-z0-9]{1,6})\/([^\/]*(?:\/(?![A-Za-z0-9]{1,6}\/)[^\/]*)*)

请参见another regex demo

允许(?s)匹配任何字符(包括换行符)的.内联DOTALL修饰符仅在前两个模式中才需要,因为第三个模式不包含,不依赖于点模式,而是使用否定的字符类[^\/]。它匹配除/以外的任何字符,包括换行符。

模式详细信息

  • (?s)-DOTALL内联修饰符
  • \/([A-Za-z0-9]{1,6})\/-/,(第1组)1到6个字母数字字符,/
  • ((?:(?!\/[A-Za-z0-9]{1,6}\/).)*)-(第2组)任何字符(.),0个或多个重复(*),但不开始匹配/[A-Za-z0-9]{1,6}/的子字符串
  • (?1)-在第二个正则表达式版本中,它与\/[A-Za-z0-9]{1,6}\/相同
  • [^\/]*(?:\/(?![A-Za-z0-9]{1,6}\/)[^\/]*)* = (?:(?!\/[A-Za-z0-9]{1,6}\/).)*-除/[^\/]*)以外的任何0+个字符,然后是/的0个或多个重复,后面没有{ {1}}个匹配的子字符串,以及[A-Za-z0-9]{1,6}\/以外的0+个字符。