Найти все действительные пользовательские упоминания в тексте с регулярным выражением - PullRequest
0 голосов
/ 20 июня 2019

Мне нужно найти все упоминания пользователей в комментарии. Это означает, что мне нужно найти все совпадения регулярных выражений 1), где есть не более одной точки и подчеркивание после @.

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

1) \B(@[a-z_.]{3,24})

Я хочу быть уверен, что символы после @ являются действительными именами пользователей (не нужно проверять, существует ли пользователь в БД)

Я использую это регулярное выражение для проверки имени пользователя:

2) '^(?!(.*?\_){2})(?!(.*?\.){2})[a-z0-9\._]{3,24}$'

Проверяет, что имя пользователя состоит из 3-24 символов и содержит 0-1 точку и подчеркивание. Имя пользователя regex не будет работать для всего текста из-за negative lookahead

Я пытался объединить регулярные выражения 1) и 2), но это не сработает.

В настоящее время я остановился здесь

Также можно использовать регулярное выражение 1) и для каждого матча использовать регулярное выражение 2). Мне это не нравится, потому что оно будет работать очень медленно на длинных комментариях ...

UPDATE : Например, у меня есть комментарий

'text @valid_username text @unvalid_username_ text @valid.username text @unvalid..username'

Мне нужны только те упоминания, где имя пользователя состоит из 3-24 символов и не содержит более одной точки и подчеркивания

1 Ответ

1 голос
/ 21 июня 2019

Вы можете рассмотреть достаточно хороший шаблон, например

r'\B@(?!(?:[a-z0-9.]*_){2})(?!(?:[a-z0-9_]*\.){2})[._a-z0-9]{3,24}\b'

См. Демонстрационный пример regex .Единственным недостатком шаблона является то, что если действительное упоминание может заканчиваться ., оно будет совпадать с этим . (см. demo ).

Подробности

  • \B@ - @ без предшествующего слова char
  • (?!(?:[a-z0-9.]*_){2}) - нет двух _ символов в любом месте после @
  • (?!(?:[a-z0-9_]*\.){2}) - нет двух . символов в любом месте после @
  • [._a-z0-9]{3,24} - от трех до двадцати четырех букв, цифр, . и _
  • \b - граница слова

Обратите внимание, что вы действительно можете использовать некоторый код Python для фильтрации результатов, полученных с помощью \B(@[a-z_.]{3,24}):

import re
s = 'text @valid_username text @unvalid_username_ text @valid.username text @unvalid..username  @validusername.'
print([x for x in re.findall(r'\B@[._a-z0-9]{3,24}', s) if x.count('.') < 2 and x.count('_') < 2 ])
# => ['@valid_username', '@valid.username', '@validusername.']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...