preg_match正则表达式匹配可能存在或不存在的字符串的一部分

问题描述 投票:0回答:2

我试图将一些文本报告解析为结构化数据。典型的线条是

 Cat. No.: 1      Location: Bottles, boxes etc
 Cat. No.: 25      Location: Woods size B      EBN: 63.1868
 Cat. No.: 24      Location: Woods size B      EBN: 12.1980.221
 Cat. No.: 20      Location: Woods size B      EBN: 4.1973
 Cat. No.: 19      Location: Woods size B

前两个值始终存在,最后一个是可选的。

/Cat\. No\.: (\d+) Location: (.+)(?: EBN: ([\d\.]+))/

适用于具有所有三个值的行但我的直觉是我需要添加一个?到最后使最后一部分可选

/Cat\. No\.: (\d+) Location: (.+)(?: EBN: ([\d\.]+))/?

然后我发现捕获组2匹配“位置:”之后的所有内容,因此例如第2行它变成'伍兹大小B EBN:63.1868'

已经在https://regex101.com/r/gd0pKH/1保存了这个,并会感激任何建议。 RegEx to match part of string that may or may not be present似乎是同一个问题,并且我提出了相同的答案,但由于某种原因,它似乎对我不起作用!

php regex
2个回答
2
投票

您可以使用以下步骤修复正则表达式:

  1. 第二个匹配组((.+))应该是ungready,或者它将匹配所有内容直到行尾:(.+?)
  2. 你应该在行$的末尾添加一个锚点,否则正则表达式会停止使用第一个匹配的表达式 - 这显然是较短的版本,在这种情况下,你的第三个匹配组将是空的。

总之,你得到这个:

Cat\. No\.: (\d+)      Location: (.+?)(?:      EBN: ([\d\.]+))?$

此外,你可以使用\s+而不是六个空格,这使表达更灵活。

Cat\. No\.: (\d+)\s+Location: (.+?)(?:\s+EBN: ([\d\.]+))?$

1
投票

您可以让Location值重复延迟,然后对行中的两个空格(对于EBN的行)或行的末尾(对于没有EBN的行)使用正向前瞻:

Cat\. No\.: (\d+)      Location: (.+?)(?=  |$)(?:      EBN: ([\d\.]+))?

https://regex101.com/r/gd0pKH/2

© www.soinside.com 2019 - 2024. All rights reserved.