![]() |
强健的松鼠 · 上海交通大学中国法与社会研究院· 10 月前 · |
![]() |
失望的跑步鞋 · flex 布局下 ...· 1 年前 · |
![]() |
开朗的烈酒 · ListView - .NET MAUI ...· 1 年前 · |
![]() |
豁达的帽子 · String Data Type - ...· 1 年前 · |
![]() |
慷慨的丝瓜 · java 判断字符串是否是json格式 - ...· 2 年前 · |
我有文本格式的数据,其中键/值对用分号分隔,后面可能跟空格,可能不是";“或";",甚至是”;“。两个字符串之间总是有一个分号,字符串以分号结尾。
键和值之间用空格分隔。
这个字符串是扁平的。从来没有嵌套过的东西。字符串总是用引号引起来,而数值从不用引号引起来。我可以指望这在输入中是一致的。举个例子,
'cheese "stilton";pigeons 17; color "blue"; why "because I said so";'
最终,这会变成
{'cheese': "stilton", 'pigeons': 17, 'color': "blue"; 'why': "because I said so"}
不同的字符串可能包含不同的键/值对,我不能提前知道将出现哪些键。所以这是同样有效的输入字符串:
mass 6.02 ; mammal "gerbil";telephone "+1 903 555-1212"; size "A1";
我认为使用正则表达式将字符串拆分成一个列表将是一个很好的开始,然后只需对列表进行二次迭代即可构建字典。就像这样
x = PATTERN.split(s)
d = {}
for i in range(0, len(x), 2):
d[x[i]] = d[x[i+1]]
比如“奶酪”,“斯蒂尔顿”,“鸽子”,17,“颜色”,“蓝色”,“为什么”,“因为我这么说”。但是我想不出一个正则表达式来表示这个表单。我最接近的是
([^;[\s]*]+)
它会返回
['', 'cheese', ' ', '"stilton"', ';', 'pigeons', ' ', '17', '; ', 'color', ' ', '"blue"', '; ', 'why', ' ', '"because', ' ', 'I', ' ', 'said', ' ', 'so"', ';']
当然,按3迭代并选择键/值对并忽略捕获的分隔符是很容易的,但我想知道是否有不同的regex不会捕获分隔符。有什么建议吗?
在这里使用
findall()
而不是
split()
可能更容易。这将允许您使用捕获组来提取您想要的部分。然后,您可以拆分组、清理等:
import re
s = 'cheese "stilton";pigeons 17; color "blue"; why "because I said so";'
pairs = re.findall(r'(\S+?) (.+?);', s)
d = {}
for k, v in pairs:
if v.isdigit():
v = int(v)
else:
v = v.strip('"')
d[k] = v
print(d)
结果
{'cheese': 'stilton',
'pigeons': 17,
'color': 'blue',
'why': 'because I said so'}
当然,这假设您没有在数据中的任何地方使用
;
。
您可以使用
r'(\w+)\s+("[^"]*"|[^\s;]+)'
若要使用
re.findall
匹配和提取数据,请对第二组值进行后处理,以便在第一个备选字符匹配时删除一个尾随字符和一个前导
"
字符,然后创建一个字典条目。
请参阅 regex demo 。
详细信息
(\w+)
-组1(关键字):一个或多个单词chars
\s+
- 1+空格字符
("[^"]*"|[^\s;]+)
-组2:
"
、除0+以外的
"
字符,然后是
"
或除空格和key之外的1个或多个字符
import re
rx = r'(\w+)\s+("[^"]*"|[^\s;]+)'
s = 'cheese "stilton";pigeons 17; color "blue"; why "because I said so";'
result = {}
![]() |
强健的松鼠 · 上海交通大学中国法与社会研究院 10 月前 |