正则表达式:获取嵌套重复组

时间:2016-11-04 13:37:20

标签: java regex regex-greedy

如何匹配重复组中的重复组?

例如,在日志文件中获取所有有效记录:

---: 
TS : 150602000006S
EC1: 02429.523
EC2: 05604.110
---
---: 
TS : 150603000006S
---: 
TS : 150603000006S
EP1: 3333.523
---

喜欢以下比赛:

[ 
  [
    ['TS ', '150602000006S'], 
    ['EC1', '02429.523'],
    ['EC2', '05604.110']
  ], 
  [
    ['TS', '150603000006S'], 
    ['EP1', '3333.523']
  ]
]

可以使用(See on regex101):

来检索单个记录属性
([A-Z0-9 ]{3,3}): ([0-9SW]+ )?([0-9\.SW]{3,})\n

但是,将正则表达式放在记录组(like seen here)中时,属性组会以重复方式停止匹配。

这怎么做得好?

1 个答案:

答案 0 :(得分:1)

为了保持这种可维护性,我会尝试将其拆分为几个正则表达式。

首先,您需要进行某种基本检查,以确保数据采用您期望的格式。我会计算以下每个表达式的出现次数。如果它们不匹配,那么就放弃*。

---:\n
---(\n|$)

一旦你知道它们是相同的,你可能想要将整个字符串与模式匹配以将其分成几个部分,例如。

---:\n.*?---(\n|$)

这表示文字---:后跟换行符,后跟尽可能少的文本(*?是懒惰的),后跟换行符或字符串结尾。你需要使用 s ingle line flag运行它。

这将为您的示例字符串提供三个匹配项。然后,您可以在每个结果匹配上运行您的模式。

*放弃可能看似简单的方法,但很难对格式错误的数据进行任何准确的猜测。考虑到您之前的示例,如果我们想要规范化这些数据,我们有两个选择,两者都作为注释添加:

---:
TS : 150602000006S
EC1: 02429.523
EC2: 05604.110
---
---:
TS : 150603000006S
       // Add a closing tag here?
---:   // Remove this opening tag?
TS : 150603000006S
EP1: 3333.523
---

如果猜错了会有什么后果?在出现错误的情况下继续进行是否有任何好处?这完全取决于您的申请。