gpt4 book ai didi

java - 几乎 JSON 的正则表达式,但不完全是

转载 作者:行者123 更新时间:2023-12-04 05:12:37 25 4
gpt4 key购买 nike

大家好,我正在尝试将一个格式良好的字符串解析为它的组成部分。该字符串非常类似于 JSON,但严格来说它不是 JSON。它们是这样形成的:

createdAt=Fri Aug 24 09:48:51 EDT 2012, id=238996293417062401, text='Test Test', source="Region", entities=[foo, bar], user={name=test, locations=[loc1,loc2], locations={comp1, comp2}}

输出就像文本块一样,此时不需要做任何特别的事情。
createdAt=Fri Aug 24 09:48:51 EDT 2012 
id=238996293417062401
text='Test Test'
source="Region"
entities=[foo, bar]
user={name=test, locations=[loc1,loc2], locations={comp1, comp2}}

使用以下表达式,我可以分离出大部分字段
,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))(?=(?:[^']*'[^']*')*(?![^']*'))

这将在所有逗号上拆分而不是在任何类型的引号中,但我似乎无法跳到它在逗号上拆分而不是在括号或大括号中的位置。

最佳答案

因为您想处理嵌套的括号/括号,处理它们的“正确”方法是分别标记它们,并跟踪您的嵌套级别。因此,您确实需要为不同的 token 类型使用多个正则表达式,而不是单个正则表达式。

这是 Python,但转换为 Java 应该不会太难。

# just comma
sep_re = re.compile(r',')

# open paren or open bracket
inc_re = re.compile(r'[[(]')

# close paren or close bracket
dec_re = re.compile(r'[)\]]')

# string literal
# (I was lazy with the escaping. Add other escape sequences, or find an
# "official" regex to use.)
chunk_re = re.compile(r'''"(?:[^"\\]|\\")*"|'(?:[^'\\]|\\')*[']''')

# This class could've been just a generator function, but I couldn;'t
# find a way to manage the state in the match function that wasn't
# awkward.
class tokenizer:
def __init__(self):
self.pos = 0

def _match(self, regex, s):
m = regex.match(s, self.pos)
if m:
self.pos += len(m.group(0))
self.token = m.group(0)
else:
self.token = ''
return self.token

def tokenize(self, s):
field = '' # the field we're working on
depth = 0 # how many parens/brackets deep we are
while self.pos < len(s):
if not depth and self._match(sep_re, s):
# In Java, change the "yields" to append to a List, and you'll
# have something roughly equivalent (but non-lazy).
yield field
field = ''
else:
if self._match(inc_re, s):
depth += 1
elif self._match(dec_re, s):
depth -= 1
elif self._match(chunk_re, s):
pass
else:
# everything else we just consume one character at a time
self.token = s[self.pos]
self.pos += 1
field += self.token
yield field

用法:
>>> list(tokenizer().tokenize('foo=(3,(5+7),8),bar="hello,world",baz'))
['foo=(3,(5+7),8)', 'bar="hello,world"', 'baz']

这个实现需要一些捷径:
  • 字符串转义真的很懒:它只支持\"在双引号字符串和 \' 中在单引号字符串中。这很容易修复。
  • 它只跟踪嵌套级别。它不验证括号是否与括号匹配(而不是括号)。如果您在乎可以更改 depth进入某种堆栈并将括号/括号插入/弹出。
  • 关于java - 几乎 JSON 的正则表达式,但不完全是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14714584/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com