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

У меня есть требование, где мне нужно использовать Regex для анализа запроса от пользователя.

Например, пользователь может искать ссылки с форматом запроса, например

link to <keyword> from <person name>
link to <keyword> from <person name> shared <time>

например

link to connect form from sandeep agarwal => keyword=connect form, person-name=sandeep agarwal
link to sharepoint ppt from mathews => keyword=sharepoint ppt, person-name=mathews 
link to sharepoint design from Gronvik yesterday => keyword=sharepoint design, person-name=Gronvik, time=yesterday

Я упомянул выше ожидаемые значения группы захвата.

My Regex:

"Ссылка на (? [Az] +) from (? [] +) (?: общая) (? [az] +) "

Вот мой ответ на 3 вышеупомянутых запроса

Match 1
Full match = link to connect link from sandeep agarwal
Group `keyword` = connect form
Group `name`= sandeep agarwal   

Match 2
Full match = link to sharepoint git from sapna
Group `keyword` = sharepoint ppt
Group `name`= mathews           

Match 3 - **This is where things go wrong**
Full match = link to sharepoint git from sapna grover shared yesterday
Group `keyword` = sharepoint design
Group `name`= Gronvik shared yesterday

In вышеупомянутый 3-й ответ, я получаю «Gronvik shared вчера» как «имя группы», но идеальным сценарием было бы имя = Gronvik и время = «вчера». Я пробовал много подходов от позитивного взгляда на будущее, но что-то или другие сценарии начинают нарушаться.

Ключевое слово "shared" может присутствовать не каждый раз, но когда оно присутствует, моя группа "name" должна захватывать имя до тех пор, пока не будет передано (исключая его), а группа "time" - время только если в запросе присутствует «общий доступ». Было бы очень полезно, если бы кто-то мог указать верное направление.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

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

(?i)^Link\s+to\s+(?<keyword>[a-z ]+) from (?<name>.*?)(?:\s+shared\s+(?<time>[a-z]+))?$

См. Демоверсию regex .

Подробности

  • (?i) - флаг без учета регистра
  • ^ - начало строки (или строки, если m включена многострочная опция)
  • Link to - текстовый текст
  • (?<keyword>[a-z ]+) - группа «ключевое слово»: 1+ буквы или пробелы
  • from - буквенный текст
  • (?<name>.*?) - группа «имя»: любые 0+ символов, как можно меньше
  • (?:\s+shared\s+(?<time>[a-z]+))? - необязательная последовательность
    • \s+ - 1+ пробелов
    • shared - буквенная подстрока
    • \s+ - 1+ пробелы
    • (?<time>[a-z]+) - группа "время": 1+ буквы
  • $ - конец строки / строки.
0 голосов
/ 06 марта 2020

link to (.*?) from (.*?)( shared (.*))?$

Используйте .*? для ленивых повторителей (ленивый = не жадный)

...