PCRE字符类减法

时间:2019-03-11 05:04:32

标签: php regex pcre

我有一些条目的数据流。

  • 条目包含1个必填字段和1个可选字段。
  • 字段之间用分号;隔开。
  • 字段包含任何可打印的符号 EXSEMPT SEMICOLON ;
  • 必填字段的长度应为1-60个符号。
  • 可选字段的长度可以是0-60个符号。

我想匹配条目中的所有字段。 我使用否定的超前断言从[:print:] POSIX字符类中减去分号,但似乎不适用于长度受限制的字段。

我的数据:

[1427894078] SERV;ICE ALERT: example.com ;Current Load;CRITICAL;SOFT;3;CRITICAL - load average: 1.96, 1.29, 0.59

我的正则表达式(PCRE):

((?!;)[[:print:]]{1,60});((?!;)[[:print:]]{0,60})

我希望得到的东西:

Match 1:
Group 1: [1427894078] SERV
Group 2: ICE ALERT: example.com 

Match 2:
Group 1: Current Load
Group 2: CRITICAL

Match 3:
Group 1: SOFT
Group 2: 3

我错误得到的东西:

Match 1:
Group 1: [1427894078] SERV;ICE ALERT: example.com ;Current Load
Group 2: CRITICAL;SOFT;3;CRITICAL - load average: 1.96, 1.29, 0.59

演示:https://regex101.com/r/3uObB5/2

1 个答案:

答案 0 :(得分:2)

您完全亲密。正则表达式的唯一问题是您没有在量化聚类中包括超前行为:

  • (?!;)[[:print:]]{1,60}应该是(?:(?!;)[[:print:]]){1,60}

现在,它与正确的字符块匹配(请参见实时演示here):

((?:(?!;)[[:print:]]){1,60});((?:(?!;)[[:print:]]){0,60})

但是,还有更好的选择(请参见现场演示here):

([^\p{C};]{1,60});([^\p{C};]{0,60})