Regex捕获重复模式中每个组的第一次出现



假设我有以下文本:

Name: John DoetAddress: Street 123 ABCtCity: MyCity

我有一个正则表达式(有点复杂,但归根结底是这样(:

^(?:(?:(?:Name: (.+?))|(?:Address: (.+?))|(?:City: (.+?)))t*)+$

它有三个捕获组,可以捕获Name、Address和City的值(如果它们出现在文本中(。以下是更多示例:https://regex101.com/r/37nemH/6.EDIT排序不是预先固定的,也可能出现字段由t字符分隔的而不是的情况。

现在这一切都很好,我唯一的小问题是当一个字段在同一文本中出现两次时,正如我在regex101:上的最后一个例子所示

Name: John DoetAddress: Street 123 ABCtCity: MyCitytAddress: Other Address

我希望第二个捕获组匹配第一个地址,即Street 123 ABC,并且最好让第二个事件在"城市"组内匹配,即

1: John Doe
2: Street 123 ABC
3: MyCitytAddress: Other Address

从概念上讲,我试着用一个否定的后备来做这件事,例如用(?:(?<!.*Address: )Address: (.+?))替换(?:Address: (.+?)),即确保另一个Address:标签不会在文本中的某个地方进行Address:匹配。但是,负向后看不允许任意长度,所以这显然是行不通的。

这可以使用regex实现吗?如何实现?

对于您提出的问题,您可以将此正则表达式与条件构造一起使用:

^.*?(?:(?:Name: (.+?)|(Address: )(.+?)|City: ((?(2).*?Address: )*.+?))t*)+$

RegEx演示

您的值在捕获的组1、3、4中可用。

捕获组2用于文字标签"Address: "

这里,(?(2).*?Address: )*是一个条件构造,这意味着如果捕获的组2存在,则在组4中匹配文本,直到找到下一个Address:(0个或更多个匹配(。

对于文本Name: John Doe Address: Street 123 ABC City: MyCity Address: Second address,它将具有以下匹配项:

Group 1.    169-177 `John Doe`
Group 2.    178-187 `Address: `
Group 3.    187-201 `Street 123 ABC`
Group 4.    210-240 `MyCity Address: Second address`

如果单词顺序可以是任意的,并且部分或全部项目可能会丢失,那么使用3个单独的模式来提取所需的位会容易得多。

名称(演示(:

^.*?Name:s*(.*?)(?=s*(?:Name:|Address:|City:|$))

城市(演示(:

^.*?City:s*(.*?)(?=s*(?:Name:|Address:|City:|$))

地址(演示(:

^.*?Address:s*(.*?)(?=s*(?:Name:|Address:|City:|$))

详细信息

  • ^-字符串的开头
  • .*?-换行字符以外的任何0+个字符,尽可能少
  • Address:-一个用于查找预期匹配项的关键字
  • s*-0+空白
  • (.*?)-第1组:除换行字符外的任何0+个字符,尽可能少
  • (?=s*(?:Name:|Address:|City:|$))-最多但不包括0个或多个空格,后面跟有Name:Address:City:或字符串末尾

相关内容

最新更新