在空格上拆分,但如果有冒号后跟空格或引号

时间:2016-05-13 05:10:57

标签: python regex

我有一个像这样的字符串

str = 'name: phil age : 23 range: 33, 45 address: "main ave US"' 

被标记为

['name: phil', 'age : 23', 'range: 33, 45' 'address: "main ave US"']

2 个答案:

答案 0 :(得分:2)

示例字符串1

>>> import re
>>> str = 'name: phil age : 23 range: 33, 45 address: "main ave US"' 
>>> re.findall(r'\w+\s*:\s*(?:"[^"]*"|.*?(?=\w+\s*:\s*|$))', str)
['name: phil ', 'age : 23 ', 'range: 33, 45 ', 'address: "main ave US"']

示例字符串2

>>> str = 'name: phil age : 23 range: 33, 45 address: "main ave US" abcd : xyz' 
>>> re.findall(r'\w+\s*:\s*(?:"[^"]*"|.*?(?=\w+\s*:\s*|$))', str)
['name: phil ', 'age : 23 ', 'range: 33, 45 ', 'address: "main ave US"', 'abcd : xyz']

示例字符串3

>>> str = 'name: phil age : 23 range: 33, 45'
>>> re.findall(r'\w+\s*:\s*(?:"[^"]*"|.*?(?=\w+\s*:\s*|$))', str)
['name: phil ', 'age : 23 ', 'range: 33, 45']

要修剪每个匹配的前导和尾随空格,您可以使用:

>>> list(map(lambda x:x.strip(), re.findall(r'\w+\s*:\s*(?:"[^"]*"|.*?(?=\w+\s*:\s*|$))', str)))
['name: phil', 'age : 23', 'range: 33, 45']

使用的正则表达式是:\w+\s*:\s*(?:"[^"]*"|.*?(?=\w+\s*:\s*|$))

边缘案例:

>>> str='word1 word2 name: phil age : 23 range: 33, 45'
>>> list(map(lambda x:x.strip() if ':' in x else list(map(lambda s:s.strip(), x.split())), re.findall(r'\w+\s*:?\s*(?:"[^"]*"|.*?(?=\w+\s*:\s*|$))?' , str)))
[['word1', 'word2'], 'name: phil', 'age : 23', 'range: 33, 45']

拥有上述结构后,您可以使用here

中给出的任何一个答案来展平列表

答案 1 :(得分:1)

这个正则表达式应该非常稳定。它仅检查键名后跟冒号,并将其视为匹配的开头,并将其视为未包括结尾,使用正向前瞻。

根据您希望如何进一步处理它,您可以使用简单的变体:

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

这将匹配整个键/值对,包括所有空格。

Check this regex out on regex101.com

如果你打算在结肠上分开对,例如要将它们存储在字典中,您也可以使用这个稍微修改过的正则表达式,为每对返回一个元组(key, value),前导和尾随空格已被剥离:

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

Check this regex out on regex101.com

这是一个如何使用两个正则表达式的Python示例:

import re

pattern1 = r'\w+\s*:.*?(?=(?:\w+\s*:)|$)'
pattern2 = r'(\w+)\s*:\s*(.*?)\s*(?=(?:\w+\s*:)|$)'
data = 'name: phil age : 23 range: 33, 45 address: "main ave US"' 

print('Pattern 1:', re.findall(pattern1, data))
print('Pattern 2:', re.findall(pattern2, data))

输出:

Pattern 1: ['name: phil ', 'age : 23 ', 'range: 33, 45 ', 'address: "main ave US"']
Pattern 2: [('name', 'phil'), ('age', '23'), ('range', '33, 45'), ('address', '"main ave US"')]

See this code running on ideone.com