Опираясь на усилия мистера Топфа:
import re
rx = re.compile("((?:@\w+ +)+)(.*)")
t='@abc @def @xyz Hello this part is text and my email is foo@ba.r'
a,s = rx.match(t).groups()
l = re.split('[@ ]+',a)[1:-1]
print l
print s
печать:
['abc', 'def', 'xyz']
Здравствуйте, эта часть является текстом, и мой адрес электронной почты foo@ba.r
Справедливо призван к ответу hasen j , позвольте мне уточнить, как это работает:
/@\w+ +/
соответствует одному тегу - @, за которым следует хотя бы один буквенно-цифровой или _, за которым следует хотя бы один пробел. + является жадным, поэтому, если есть несколько пробелов, он захватит их все.
Чтобы соответствовать любому количеству этих тегов, нам нужно добавить плюс (одну или несколько вещей) в шаблон для тега; поэтому нам нужно сгруппировать его в скобках:
/(@\w+ +)+/
, который соответствует одному или нескольким тегам и, будучи жадным, соответствует всем им. Однако эти скобки теперь смешиваются с нашими группами захвата, поэтому мы отменяем это, превращая их в анонимную группу:
/(?:@\w+ +)+/
Наконец, мы превращаем это в группу захвата и добавляем еще одну, чтобы смести остальные:
/((?:@\w+ +)+)(.*)/
Последняя разбивка для подведения итогов:
((?:@\w+ +)+)(.*)
(?:@\w+ +)+
( @\w+ +)
@\w+ +
Обратите внимание, что при рассмотрении этого я улучшил его - \ w не обязательно должен быть в наборе, и теперь он допускает наличие нескольких пробелов между тегами. Спасибо, hasen-j!