我正在实现某种解析器,我需要找到并反序列化嵌入到其他半结构化数据中的json对象 。我使用了regexp:
\\{\\s*title.*?\\}
找到对象
{title:'Title'}
但它不适用于嵌套对象,因为表达式仅匹配第一个找到的右括号。对于
{title:'Title',{data:'Data'}}
匹配
{title:'Title',{data:'Data'}
因此字符串对于反序列化变得无效。 我知道有一个贪婪的业务,但我不熟悉正则表达式。你可以帮我扩展表达式以消耗所有可用的结束花括号。
更新
要明确的是,这是尝试从带有嵌入式JSON的HTML + JS等半结构化数据中提取JSON数据。我正在使用GSon JAVA lib来实际解析提取的JSON。
答案 0 :(得分:4)
正如其他人所建议的那样,一个成熟的JSON解析器可能就是这样。如果要匹配上面的简单示例中的键值对,可以使用:
(?<=\{)\s*[^{]*?(?=[\},])
输入字符串
{title:'Title', {data:'Data', {foo: 'Bar'}}}
匹配:
1. title:'Title'
2. data:'Data'
3. foo: 'Bar'
答案 1 :(得分:2)
感谢@Sanjay T. Sharma指出我“支持匹配”,因为我最终对贪婪的表达有了一些了解,也感谢其他人最初说我不该做的事情。 幸运的是,结果表明使用贪婪的表达变体
是可以的\\{\s*title.*\\}
因为右括号之间没有非JSON数据。
答案 2 :(得分:2)
此递归Perl / PCRE正则表达式应该能够匹配任何有效的JSON或JSON5对象,包括嵌套对象和边缘情况,例如JSON字符串或JSON5注释中的花括号:
/(\{(?:(?>[^{}"'\/]+)|(?>"(?:(?>[^\\"]+)|\\.)*")|(?>'(?:(?>[^\\']+)|\\.)*')|(?>\/\/.*\n)|(?>\/\*.*?\*\/)|(?-1))*\})/
当然,这有点难以理解,因此您可能更喜欢带注释的版本:
m{
( # Begin capture group (matching a JSON object).
\{ # Match opening brace for JSON object.
(?: # Begin non-capturing group to contain alternations.
(?>[^{}"'\/]+) # Match a non-empty string which contains no braces, quotes or slashes, without backtracking.
| # Alternation; next alternative follows.
(?>"(?:(?>[^\\"]+)|\\.)*") # Match a double-quoted JSON string, without backtracking.
| # Alternation; next alternative follows.
(?>'(?:(?>[^\\']+)|\\.)*') # Match a single-quoted JSON5 string, without backtracking.
| # Alternation; next alternative follows.
(?>\/\/.*\n) # Match a single-line JSON5 comment, without backtracking.
| # Alternation; next alternative follows.
(?>\/\*.*?\*\/) # Match a multi-line JSON5 comment, without backtracking.
| # Alternation; next alternative follows.
(?-1) # Recurse to most recent capture group, to match a nested JSON object.
)* # End of non-capturing group; match zero or more repetitions of this group.
\} # Match closing brace for JSON object.
) # End of capture group (matching a JSON object).
}x
答案 3 :(得分:0)
这绝对是可怕的,我无法相信我实际上是在为这个解决方案添加我的名字,但是你找不到Javascript块中的第一个{
字符并尝试解析剩余的字符通过适当的JSON解析库?如果它有效,你就得到了一个匹配。如果没有,请继续阅读直至下一个{
字符并重新开始。
那里有一些问题,但它们可能可以解决:
<script>...</script>
块。一旦找到第一个{
,就会有一个改进,就是找一个匹配的}
(一个简单的计数器,只要你找到{
并且递减就会增加当你发现}
应该做的伎俩)。尝试将生成的字符串解析为JSON。迭代直到它工作或你已经用完了可能的块。
这是丑陋的,hackish,永远不应该成为生产代码。我得到的印象是,你只需要批量工作,这就是为什么我甚至建议它。