2017-04-27 89 views
0

第一次在这里发布。按正则表达式分割,并添加匹配词典

我想1)分析了以下文字:"keyword: some keywords concept :some concepts"

和2)储存到字典:['keyword']=>'some keywords', ['concept']=>'some concepts'

在每个“冒号”之前可能有0或1个'空间'。以下是我到目前为止所尝试的。

sample_text = "keyword: some keywords concept :some concepts" 

p_res = re.compile("(\S+\s?):").split(sample_text) # Task 1 

d_inc = dict([(k, v) for k,v in zip (p_res[::2], p_res[1::2])]) # Task 2 

但是,列表结果p_res是错误的,与指数0,从而产生错误的字典在空项。我的正则表达式有什么问题吗?

+0

如果它为空,则应该跳过第一个项目。如果在字符串的开始处找到匹配项,则正则表达式分割操作将始终在列表中的初始位置处生成一个空项目。你可以在代码中加上'如果不是p_res [0]: \t p_res = p_res [1:]'。 –

+0

或者您可以使用['if not p_res [0]: \t p_res.pop(0)'](https://ideone.com/b7A1aA) –

回答

2

使用re.findall来捕获匹配组中的列表。然后应用dict将元组列表转换为字典。

>>> import re 
>>> s = 'keyword: some keywords concept :some concepts' 
>>> dict(re.findall(r'(\S+)\s*:\s*(.*?)\s*(?=\S+\s*:|$)', s)) 
{'concept': 'some concepts', 'keyword': 'some keywords'} 
>>> 

以上正则表达式会捕获关键字,它是在两个单独的组中的对应值。

我假设输入字符串只包含键值对,而键不包含任何空格字符。

DEMO

+0

删除空的第一项。你的假设也是正确的。在大多数情况下,键是单个词或有时是连字符。 –

0

通过此线只需更换任务1:

p_res = re.compile("(\S+\s?):").split(sample_text)[1:] # Task 1 

这将始终忽略由re.split返回的(通常是空的)元素。

背景:为什么re.split返回空的第一个结果?

应该采取什么程序做这个输入:

sample_text = "Hello! keyword: some keywords concept :some concepts" 

在输入开头的文字Hello!不适合您的问题(假定的定义是,用键输入开始)。

你想忽略它吗?如果出现异常,您是否想要引发异常?你想用特殊的键将它添加到你的字典吗?

re.split不想为您做出决定:它返回出现的任何信息并作出决定。在我们的解决方案中,我们只是忽略第一个键出现之前的任何内容

+0

感谢您指出我们的潜在异常。我认为这将在预处理任务中处理。你的解决方案解决了这个问题,但我不得不接受@Avinash Raj答案,因为他的正则表达式比我的更强大。 –