我有一个格式的字符串:
t='@abc @def Hello this part is text'
我想得到这个:
l=["abc", "def"] s='Hello this part is text'
我这样做了:
a=t[t.find(' ',t.rfind('@')):].strip() s=t[:t.find(' ',t.rfind('@'))].strip() b=a.split('@') l=[i.strip() for i in b][1:]
它大部分都有效,但是当文本部分有'@'时它会失败.例如,何时:
t='@abc @def My email is red@hjk.com'
它失败.@names一开始就存在,@ name之后可能有文本,可能包含@.
很明显,我可以初始添加一个空格并找出没有'@'的第一个单词.但这似乎不是一个优雅的解决方案.
解决这个问题的pythonic方法是什么?
毫不掩饰地建立MrTopf的努力:
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!
t='@abc @def Hello this part is text' words = t.split(' ') names = [] while words: w = words.pop(0) if w.startswith('@'): names.append(w[1:]) else: break text = ' '.join(words) print names print text
这个怎么样:
按空间分裂.
foreach一词,检查
2.1.如果单词以@开头,则推送到第一个列表
2.2.否则只用空格加入剩余的单词.