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

Обычно я использую регулярные выражения, как будто это родной язык, но сегодня я озадачен этой загадкой. Мне нужно захватить весь текст строки, кроме последнего хэштега. Любые хэштеги, кроме последнего, должны быть включены, и он также должен совпадать, если хэштегов нет вообще.

Тестовый пример 1:

  • Вход: Foo bar #baz
  • Соответствие: Foo bar

Тестовый пример 2:

  • Ввод: Foo bar #baz #qux
  • Соответствие: Foo bar #baz

Тестовый пример 3:

  • Ввод: Foo bar
  • Соответствие: Foo bar

Из-за среды I Я использую это в (Zapier), у меня есть жесткое ограничение, что мне нужна соответствующая строка в одной группе захвата с тем же номером группы независимо от случая. Zapier использует движок Python, FWIW.

Контекст - это автоматическая публикация фотографий из Instagram в Twitter, но при этом необходимо ограничить длину до 280 символов. Поскольку функция усечения Zapier не позволяет обрезать чистые границы слов, существует вероятность того, что в середине хэштега могут закончиться 280 символов, что может привести к неприятным результатам, если Twitter автоматически связывает его. (Усечение Zapier позволяет добавлять многоточие, что смягчает проблему для обычных слов.) Поскольку включать каждый хэштег не критично, я хочу выбросить последний, если он был усечен.

Ответы [ 3 ]

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

Можно использовать развернутый метод l oop. Вероятно, это самый быстрый способ сделать это.

[^#]*(?:\#(?![^#]*$)[^#]*)*

см. https://regex101.com/r/vlEows/1/tests

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

Вы можете сопоставить следующее регулярное выражение, которое определяет, заканчивается ли строка хэштегом.

^(?:(?=.*#\w+$).*(?=#\w+$)|.*)

Запустите двигатель!

Если вам нужно группу захвата используйте $0, которая содержит полное совпадение.

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

^              : match beginning of string
(?:            : begin non-capture group
  (?=.*#\w+$)  : positive lookahead asserts that the string
                 ends with a hashtag
  .*           : match 0+ characters
  (?=#\w+$)    : positive lookahead asserts that the next character
                 begins a hashtag at the end of the string
|              : or
  .*           : match 0+ characters
)              : end non-capture group

В качестве альтернативы можно удалить группу без захвата и повторить привязка начала строки:

^(?=.*#\w+$).*(?=#\w+$)|^.*
1 голос
/ 14 июля 2020

Как только я закончил печатать это, я нашел свое собственное решение (ура, резинка это). Подумал, что отправлю его для всех, кому понадобится это конкретное c странное решение:

((^[^#]+$)|(?:.|\n)+)(?(2)|\s#[^#]+)

Результаты тестов: https://regex101.com/r/RNGVSL/2/tests

Обновление

Более простой ответ от Виктора Стрибьева в комментариях:

(?s)^(.*?)(?:\s*#[^\s#]+)?$

Результаты тестов: https://regex101.com/r/RNGVSL/3/tests

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...