[^{}]
不會在引號引起賬戶部分採取,而是可以將其替換爲:[^"{}]|"[^"]*"
你可以用這種模式做到這一點:
{[^"{}]*+(?:"[^"]*+"[^"{}]*+|(?R)[^"{}]*+)*+}
demo
另外,如果您想要處理引用部分中的轉義引號(帶反斜槓):
{[^"{}]*+(?:"[^"\\]*+(?s:\\.[^"\\]*)*+"[^"{}]*+|(?R)[^"{}]*+)*+}
種
demo
這兩種模式使用展開的設計,是更有效的。簡而言之,您不需要編寫(A|B)*
,而是編寫A*(BA*)*
,這需要更少的步驟。
佔有量詞*+
是爲了防止當大括號在字符串中某個位置不平衡時防止大量回溯。這種方式在這個位置會很快失敗。
顯然,這兩種模式並沒有完全描述json語法。隨意使用命名組和(?(DEFINE)...)
功能來做到這一點,這遠非不可能(*)。但是您也可以使用第二種模式來提取json子字符串,然後使用您選擇的json解析器來檢查它們。
(*)這樣的事情:
~
\g<object>
(?(DEFINE)
(?<string> " [^"\\]*+ (?s: \\. [^"\\]*+)*+ ")
(?<table> \[ (?: \s* \g<value> (?: \s* , \s* \g<value>)*+)? \s* ])
(?<object> {
(?: \s* \g<key> \s* : \s* \g<value>
(?: \s* , \s* \g<key> \s* : \s* \g<value>)*+
)? \s* }
)
(?<boolean> [Tt]rue | [Ff]alse)
(?<number> (?: [0-9]+ (?: \. [0-9]*)? | \.[0-9]+)
(?: [Ee] -? [0-9]+)?)
(?<key> \g<string> (?<= [^"]" | \\""))
(?<value> \g<table> | \g<object> | \g<string>
| \g<number> | \g<boolean> | null)
)
~x
你只需要比更精確'[^ {}]'和分別描述部件之間引號包圍。 –