Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按空格拆分,但如果冒号后跟空格或引号中有空格,则不拆分_Python_Regex - Fatal编程技术网

Python 按空格拆分,但如果冒号后跟空格或引号中有空格,则不拆分

Python 按空格拆分,但如果冒号后跟空格或引号中有空格,则不拆分,python,regex,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"'] 示例字符串1 >>> import re >>> str = 'name: phil age : 23 range: 33, 45 address: "main

我有一根这样的绳子

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

['name: phil', 'age : 23', 'range: 33, 45' 'address: "main ave US"']
示例字符串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']
有了上述结构后,您可以使用给定的任何一个答案展平列表

示例字符串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']

一旦你有了上面的结构,你就可以使用给出的任何一个答案将列表展平,这个正则表达式应该是非常稳定的。它只检查后跟冒号的键名,并使用正向前瞻将其视为匹配的开始和未包含的结束

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

\w+\s*:.*?(?=(?:\w+\s*:)|$)
这将匹配整个键/值对,包括所有空格


如果要在冒号处拆分这些对,例如,要将它们存储在字典中,您还可以使用这个稍加修改的正则表达式,它为每对返回一个元组
(key,value)
,前导和尾随空格已被剥离:

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


下面是如何使用这两个正则表达式的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"')]

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

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

\w+\s*:.*?(?=(?:\w+\s*:)|$)
这将匹配整个键/值对,包括所有空格


如果要在冒号处拆分这些对,例如,要将它们存储在字典中,您还可以使用这个稍加修改的正则表达式,它为每对返回一个元组
(key,value)
,前导和尾随空格已被剥离:

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


下面是如何使用这两个正则表达式的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"')]


这并不是一个纯粹的正则表达式操作。你用什么语言?另外,这些数据的来源是什么?它看起来几乎像JSON,如果是的话,您只需要使用JSON解析器,您的预期输出甚至与您的描述不匹配。这不是regex的本意。您应该使用专用的lexer/parser。它不是JSON。源是输入框中输入的原始字符串。@dilip您使用的是哪种编程语言?问题在于字符串似乎没有遵循任何有用的模式,例如,
name:
age:
之间存在差异。这不是一个纯正则表达式操作。你用什么语言?另外,这些数据的来源是什么?它看起来几乎像JSON,如果是的话,您只需要使用JSON解析器,您的预期输出甚至与您的描述不匹配。这不是regex的本意。您应该使用专用的lexer/parser。它不是JSON。源是输入框中输入的原始字符串。@dilip您使用的是哪种编程语言?问题在于字符串似乎没有遵循任何有用的模式,例如
name:
age:
之间的差异。我本可以接受这个答案,但正如您所提到的,它并不适用于所有情况,例如str='name:phil age:23 range:33,45'感谢您的努力though@dilip用示例和新正则表达式编辑ans。。现在就来看看吧。这很有效。谢谢如果可能的话,您还可以查看一个角落案例str='word1 word2 name:phil age:23 range:33,45'=>['word1','word2','name:phil','age:23','range:33,45']。但是你按照问题回答了,我接受了。干得好。如果您也能处理上述边缘情况,我将非常高兴。+1但您可以通过一些小的修改来改进图案。1) 您可以将前瞻缩短为仅
(?=\w+\s*:|$)
(删除冒号后面的
\s*
)。2) 您根本不需要
“[^”]*“|
部分。3)将
\s*
添加到前瞻中以去除尾随空格。基本上,它应该是这样的:
\w+\s*:\s*?(?=\s*\w+\s*:\124;$)
。更新以满足OP的新要求:
\w+(?:\s*:\s*:\s*。(?=\s*:\w+\s*:):$)?
@dilip weclome:)当然..我正在做一些事情..我会尝试包括这一点并在某个时候发布我会接受这个答案,但正如你提到的,它并不适用于所有情况,例如str='name:phil age:23 range:33,45'谢谢你的努力though@dilip用示例和一个新的正则表达式编辑ans..现在看看Perfect、 这很有效。谢谢。如果可能的话,你还可以看看一个角落的例子str='word1 word2 name:phil age:23 range:33,45'=>['word1','word2','name:phil','age:23','range:33,45']。但是你按照问题回答了,我接受了。干得好。如果你也能处理上面的边缘情况,我会很高兴的。+1但是你可以通过一些小的修改来改进模式。1)你可以将前瞻缩短为
(?=\w+\s*:|$)
(删除了冒号后面的
\s*
).2)您根本不需要
“[^”]*“|
部分。3) 将
\s*
添加到前瞻中,以消除尾随空格。基本上它应该是这样的:
\w+\s*:\s*?(?=\s*\w+\s*:|$)
。使用OP的新要求进行更新:
\w+(?:\s*:\s*?(?=\s*\w+\s*:|$)?
@dilip weclome:)确定。。我正忙着。。我会试着把它包括进去,然后在某个时候发布