我正在实现某种解析器,我需要定位和反序列化嵌入到其他半结构化数据中的json 对象。我使用了正则表达式:
\\{\\s*title.*?\\}
Run Code Online (Sandbox Code Playgroud)
定位对象
{title:'Title'}
Run Code Online (Sandbox Code Playgroud)
但它不适用于嵌套对象,因为表达式只匹配第一个找到的右大括号。为了
{title:'Title',{data:'Data'}}
Run Code Online (Sandbox Code Playgroud)
它匹配
{title:'Title',{data:'Data'}
Run Code Online (Sandbox Code Playgroud)
所以字符串对于反序列化无效。我知道考虑到贪婪的业务,但我不熟悉正则表达式。你能帮我扩展表达式以使用所有可用的右大括号吗?
更新:
需要明确的是,这是一种尝试从 HTML+JS 等带有嵌入 JSON 的半结构化数据中提取 JSON 数据的尝试。我正在使用 GSon JAVA lib 来实际解析提取的 JSON。
正如其他人所建议的那样,一个成熟的 JSON 解析器可能是要走的路。如果要匹配上面简单示例中的键值对,可以使用:
(?<=\{)\s*[^{]*?(?=[\},])
Run Code Online (Sandbox Code Playgroud)
对于输入字符串
{title:'Title', {data:'Data', {foo: 'Bar'}}}
Run Code Online (Sandbox Code Playgroud)
这匹配:
1. title:'Title'
2. data:'Data'
3. foo: 'Bar'
Run Code Online (Sandbox Code Playgroud)
这个递归 Perl/PCRE 正则表达式应该能够匹配任何有效的 JSON 或 JSON5 对象,包括嵌套对象和边缘情况,例如 JSON 字符串或 JSON5 注释中的大括号:
/(\{(?:(?>[^{}"'\/]+)|(?>"(?:(?>[^\\"]+)|\\.)*")|(?>'(?:(?>[^\\']+)|\\.)*')|(?>\/\/.*\n)|(?>\/\*.*?\*\/)|(?-1))*\})/
Run Code Online (Sandbox Code Playgroud)
当然,这有点难读,所以你可能更喜欢评论版本:
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
Run Code Online (Sandbox Code Playgroud)
感谢@Sanjay T. Sharma 指出我“大括号匹配”,因为我最终对贪婪表达式有了一些了解,也感谢其他人最初说我不应该做什么。幸运的是,事实证明使用贪婪的表达式变体是可以的
\\{\s*title.*\\}
Run Code Online (Sandbox Code Playgroud)
因为右括号之间没有非 JSON 数据。
归档时间: |
|
查看次数: |
29213 次 |
最近记录: |