Регулярное выражение для захвата всего после необязательного токена - PullRequest
1 голос
/ 10 июля 2020

У меня есть поля, которые содержат данные в следующих возможных форматах (каждая строка - это разные возможности):

AAA - Something Here  
AAA - Something Here - D  
Something Here 

Обратите внимание, что первая группа букв (AAA) может иметь разную длину.

Я пытаюсь захватить «Что-то здесь» или «Что-то здесь - D» (если оно существует) с помощью PCRE, но я не могу заставить регулярное выражение правильно работать во всех трех случаях. Я пробовал:

- (.*), который отлично работает для случаев 1 и 2, но, очевидно, не 3;

(?<= - )(.*), который также отлично работает для случаев 1 и 2;

(?! - )(.+)| - (.+) работает для случаев 2 и 3, но не 1.

Я чувствую, что нахожусь на грани этого, но не могу взломать его.

Заранее спасибо за вашу помощь.

Edit: Я понял, что мне неясны мои требования. Если в конце стоит «- D» (буква в данных может быть произвольной, но должна быть только одним символом), это также необходимо зафиксировать.

Ответы [ 3 ]

1 голос
/ 10 июля 2020

О шаблонах, которые вы пробовали:

  • - (.*) Этот шаблон будет соответствовать первому вхождению - , за которым следует остальная часть строки. Это будет слишком много для второго примера, так как .* также будет соответствовать второму вхождению -
  • (?<= - )(.*) Этот шаблон будет соответствовать тому же, что и первый пример, без - , поскольку он утверждает, что оно должно происходить непосредственно слева
  • (?! - )(.+)| - (.+) Этот шаблон использует отрицательный просмотр вперед, который утверждает, что то, что находится прямо справа, не является (?! - ). Поскольку ни один из примеров не начинается с - , вся строка будет сопоставлена ​​сразу после отрицательного просмотра вперед из-за .+, а вторая часть после чередования | не будет оцениваться

Если первая группа букв может иметь разную длину, вы можете сделать соответствие либо указанным c, совпадающим с 1 или более прописными буквами [A-Z]+, либо 1+ символами слова \w+.

To Чтобы получить более широкое соответствие, вы можете сопоставить 1 или несколько символов без пробелов, используя \S+

^(?:\S+\h-\h)?\K\S+(?:\h(?!-\h)\S+)*

Пояснение

  • ^ Начало строки
  • (?:\S+\h-\h)? Необязательно сопоставить первую группу символов без пробелов, за которой следует - между горизонтальными символами с пробелами
  • \K Очистить буфер сопоставления (забыть то, что соответствует в настоящее время)
  • \S+ Сопоставьте 1+ непробельных символов
  • (?: Группа без захвата
    • \h(?!-\h) Сопоставьте горизонтальный пробельный символ и подтвердите, что то, что находится прямо справа, не - f после другого горизонтального символа пробела
    • \S+ Сопоставить 1+ непробельных символов
  • )* Закройте группу без пробелов и повторите 1+ раз, чтобы сопоставить больше слов "разделены пробелами

Regex demo

Edit

Чтобы сопоставить необязательный дефис и завершающий одиночный символ, вы можете добавить необязательную группу без захвата (?:-\h\S\h*)?$ и подтвердить конец строки, если шаблон должен соответствовать всей строке:

^(?:\S+\h-\h)?\K\S+(?:\h(?!-\h)\S+)*\h*(?:-\h\S\h*)?$
                                       

Regex demo

1 голос
/ 10 июля 2020

Вы можете использовать

^(?:.*? - )?\K.*?(?= - | *$)
^(?:.*?\h-\h)?\K.*?(?=\h-\h|\h*$)

См. демонстрацию регулярных выражений

Подробности

  • ^ - начало строки - (?:.*? - )? - необязательная группа без захвата, соответствующая любым символам 0+, кроме символов разрыва строки, как можно меньше до первого space-space
  • \K - оператор сброса соответствия
  • .*? - любые символы 0+, кроме символов разрыва строки, как можно меньше
  • (?= - | *$) - space-space или 0+ пробелов до конца строки должны следовать сразу справа .

Обратите внимание, что \h соответствует любым горизонтальным пробельным символам.

0 голосов
/ 14 июля 2020
^(?:[A-Z]+ - \K)?.*\S

demo

Поскольку «Something Here» может быть чем угодно, нет причин специально описывать возможную последнюю букву в шаблоне. Вам не нужно ничего более сложного.

В этом шаблоне я предполагаю, что вас не интересуют конечные пробелы, поэтому я закончил его \S. Если вы хотите сохранить их, удалите \S и измените предыдущий квантификатор на +.

...