正则表达式查找并替换为self的引用版本



我有一些字符串数据要转换为JSON。字符串使用非常非标准的分隔符,并且具有层次键和值。

我目前可以完成将字符串转换为类似JSON的格式,该格式可以用JSON.loads((读取到dict中,但我一直在转换"键";对自己的双重引用版本。

这是字符串

test_string = """
APPLES12:10.000^5.1234V6.456V8.111V4.222V10.000V20.000V20.12347V25.000%5.000^10.1234V16.456V15.111V5.222V15.000V15.000V6.000V25.000_BANNAS34:5.000^4.123V4.123V4.123V4.123V4.123V4.123V4.123V4.123%4.800^5.123V4.123V5.123V6.123V4.123V6.123V7.123V4.123_GRAPES:10.00^3.125%5.00^4.345%3.00^10.111_PEARS:10.00^3.123%5.000^4.234%3.000^5.67
"""

到目前为止,我拥有的是:

# copy the string into a new one
new_string = test_string
# convert (almost) to json format to be read as a dict
replace_dict = {
':': ':[n',
'V': ',',
'^': ':[',
'%': '],n',
'_': ']],n',
}
# convert separaters to make it JSON like
for k, v in replace_dict.items():
new_string = new_string.replace(k, v)
# remove trauling newline add on trailing bracket closure
new_string = new_string.strip('n')+']]'
print(new_string)

其返回更可读的";关闭";转换为JSON格式:

APPLES12:[
10.000:[5.1234,6.456,8.111,4.222,10.000,20.000,20.12347,25.000],
5.000:[10.1234,16.456,15.111,5.222,15.000,15.000,6.000,25.000]],
BANNAS34:[
5.000:[4.123,4.123,4.123,4.123,4.123,4.123,4.123,4.123],
4.800:[5.123,4.123,5.123,6.123,4.123,6.123,7.123,4.123]],
GRAPES:[
10.00:[3.125],
5.00:[4.345],
3.00:[10.111]],
PEARS:[
10.00:[3.123],
5.000:[4.234],
3.000:[5.67]]

我已经替换了字符并添加了新行,使其可读性更强。我可以";查找";使用以下表达式的所有隐式密钥:

# find all the implicit keys - these must be double quoted per JSON spec
re_pattern = r'^[^:-][^:]*'
keys = re.findall(re_pattern, new_string, re.M)
print(keys)

哪个返回:

['APPLES12', '10.000', '5.000', 'BANNAS34', '5.000', '4.800', 'GRAPES', '10.00', '5.00', '3.00', 'PEARS', '10.00', '5.000', '3.000']

更确切地说;发现";所有的键,我需要用它们自己的引号版本替换它们(然后添加大括号(,使其成为一个JSON字符串,可以用json.loads()转换为python dict

我也对其他替代方法持开放态度。。换行符是";添加";只是为了获得中间可读性,在单独的行上获取键。

速度很重要,因为这将应用于熊猫数据,其中有数百万个像这样的字符串。

你让这件事变得比需要的更难。制作一个嵌套的字典,json模块将完成剩下的工作。

从一个空字典开始:

mydict = {}

顶层对象用下划线分隔,键在冒号上分开:

for obj in test_string.split('_'):
key, content = obj.split(':', 1)

嵌套对象由%分隔,键由^分隔,列表元素由V分隔。因此嵌套循环将是

nested = {}
for item in content.split('%'):
k, v = item.split('^')
nested[k] = v.split('V')
mydict[key] = nested

现在,您可以将结果传递给json.dumps或任何其他序列化程序,它将为您正确处理所有引用和格式设置。

如果您希望在嵌套数据中使用浮动而不是字符串:

for item in content.split('%'):
k, v = item.split('^')
nested[float(k)] = list(map(float, v.split('V')))

最新更新