PCRE вычитание класса символов - PullRequest
1 голос
/ 11 марта 2019

У меня есть поток данных с некоторыми записями.

  • Записи содержат 1 обязательное поле и 1 необязательное поле.
  • Поля отделяются друг от друга точкой с запятой ;.
  • Поля содержат любые печатаемые символы. ИСКЛЮЧИТЬ ПОЛУКОЛОН ;
  • Обязательное поле должно быть длиной от 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 Ответ

2 голосов
/ 11 марта 2019

Вы совсем близко. Единственная проблема с вашим регулярным выражением состоит в том, что вы не включили предпросмотр в количественный кластер:

  • (?!;)[[:print:]]{1,60} должно быть (?:(?!;)[[:print:]]){1,60}

Теперь он соответствует правым фрагментам символов (см. Демонстрацию в реальном времени здесь ):

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

Однако, есть лучшая альтернатива (см. Демоверсию здесь ):

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