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

时间:2018-10-24 22:07:24

标签: php regex

我正在尝试将一些文本报告解析为结构化数据。典型的行是

 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行变成“ Woods size B EBN:63.1868”

已将其保存在https://regex101.com/r/gd0pKH/1,并感谢您的任何建议。 RegEx to match part of string that may or may not be present似乎是我提出的同样的问题和答案,但是由于某种原因,它似乎对我没有用!

2 个答案:

答案 0 :(得分:2)

您可以按照以下步骤修复正则表达式:

  1. 第二个匹配组((.+))应该没有准备好,否则它将匹配所有内容,直到行末:(.+?)

  2. 您应该在行$的末尾添加一个锚,否则正则表达式将以第一个匹配表达式停止-显然是较短的版本,在这种情况下,第三个匹配组将为空。

总之,您得到了:

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

此外,您可以使用\s+代替六个空格,从而使表达式更加灵活。

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

答案 1 :(得分:1)

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

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

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