RegEx для сопоставления строки, кроме определенных слов - PullRequest
2 голосов
/ 23 мая 2019

В Excel VBA я пытаюсь использовать метод регулярных выражений для сопоставления строки. Как только совпадение произойдет, я хочу, чтобы соответствующая строка включала всю строку, если только после ключевой строки не найдено ключевое слово. Проиллюстрировано иначе: шаблон регулярного выражения выглядит следующим образом:

pattern = (CHECKOUT[a-zA-Z_(/ ):]+\w+:\w+\s((AM|PM)|(am|pm))\s\-\s\w+:\w+\s((AM|PM)|(am|pm)))

вводимые строки:

1. CHECKOUT Senior Guest Services Manager FRONTENDMGR: 07:00 AM - 08:30 AM SGSM_BOOKKEEPING: 08:30 AM - 01:00 PM FRONTENDMGR: 01:00 PM - 04:00 PM

2. CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM DRY GOODS Receiving Clerk RECEIVE: 04:30 AM - 09:00 AM 

3. DRY GOODS Receiving Clerk RECEIVE: 04:30 AM - 09:00 AM CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM

с первой строкой, я хочу вернуть всю строку, но возвращается только следующее: ПРОВЕРЬТЕ Старший менеджер по обслуживанию гостей FRONTENDMGR: 07:00 - 08:30

со второй строкой, я хочу, чтобы возвращалась только первая часть строки из "CHECKOUT" в "01:00 PM", и это хорошо работает.

с третьей строкой, я хочу только вернуть часть между "CHECKOUT" и "01:00 PM".

Таким образом, единственное, что не встречается, - это первая строка, где я хочу, чтобы вся строка возвращалась, но совпадает только первая часть.

Так что мне нужно настроить шаблон так, чтобы он включал все, кроме слова «СУХИЕ ТОВАРЫ» в строке, и если это так, возвращайте только часть между словами «ПРОВЕРКА» И «AM» ИЛИ «PM».

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Вы можете обновить свой шаблон, чтобы использовать отрицательный прогноз (?! после матча, чтобы утверждать, что справа не содержится DRY GOOD

\bCHECKOUT[a-zA-Z_(/ ):]+\w+:\w+\s(?:[AP]M|[ap]m)\s-\s\w+:\w+\s(?:[AP]M|[ap]m)(?!.*\bDRY GOODS\b).*

Объяснение

  • \bCHECKOUT Совпадение буквально с границей слова, чтобы слово не входило в большее слово
  • [a-zA-Z_(/ ):]+ Совпадение 1+ раз с любым из перечисленных в классе персонажей
  • \w+:\w+\s Совпадение 1+ слов, затем : и снова 1+ слов с последующими символами пробела
  • (?:[AP]M|[ap]m) Совпадение либо AM PM AM PM
  • \s-\s\w+:\w+\s Соответствует серии символов пробела, -, : и слова char
  • (?:[AP]M|[ap]m) Совпадение либо AM PM AM PM
  • (?!.*\bDRY GOODS\b) Утверждение, что справа не содержит СУХОЙ ТОВАР между границами слова
  • .* Соответствует любому символу 0+ раз

Regex demo

0 голосов
/ 23 мая 2019

Из того, что вы показываете, и из того, что вы описываете, я думаю, что это может сделать это:

\bCHECKOUT.*?(?=\s*DRY GOODS|$)

Это вернет вам данные:

CHECKOUT Senior Guest Services Manager FRONTENDMGR: 07:00 AM - 08:30 AM SGSM_BOOKKEEPING: 08:30 AM - 01:00 PM FRONTENDMGR: 01:00 PM - 04:00 PM
CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM
CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM

Мы сопоставим CHECKOUT а затем все остальное до (но не включая) DRY GOODS.И если мы не найдем DRY GOODS, мы продолжаем до конца строки.

Если строка занимает несколько строк, возможно, потребуется заменить .*? на [\s\S]*?

Если ваши данные таковы, что вы обязательно должны соответствовать AM|PM в конце, то попробуйте:

\bCHECKOUT.*(?:AM|PM)(?=.*?DRY GOODS|$)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...