對接第三方 API 時,偶爾會收到格式不標準的 JSON 字串,例如 resultmsg 欄位的值未被雙引號包裹:
{"resultcode":910005,"resultmsg":[api接口]無法查詢到應用記錄,"transactionid":""}
標準 JSON 要求字串值必須用雙引號括起來,直接解析會拋異常。需將其修正為:
{"resultcode":910005,"resultmsg":"[api接口]無法查詢到應用記錄","transactionid":""}
目標:精準定位 resultmsg 的值區間,並在兩側插入雙引號,不破壞其他結構。
採用 分組捕獲 策略,將目標字串拆解為三段:
.*?resultmsg\": (非貪婪匹配到冒號)(.*?) (非貪婪匹配值內容,直到下一組)(,.*?}) (匹配逗號及後續結構到大括號結尾)完整 Regex:(.*?resultmsg\":)(.*?)(,.*?})
import java.util.regex.*;
public class JsonFixRegex {
public static void main(String[] args) {
String json = "{\"resultcode\":910005,\"resultmsg\":[api接口]無法查詢到應用記錄,\"transactionid\":\"\"}";
// 編譯正則,三個捕獲組
Pattern p = Pattern.compile("(.*?resultmsg\":)(.*?)(,.*?})");
Matcher m = p.matcher(json);
if (m.find()) {
// group(0) 整句匹配
// group(1) 前綴 group(2) 值 group(3) 後綴
String fixed = m.group(1) + "\"" + m.group(2) + "\"" + m.group(3);
System.out.println("修正後: " + fixed);
// 輸出: {"resultcode":910005,"resultmsg":"[api接口]無法查詢到應用記錄","transactionid":""}
}
}
}
.*?:關鍵在於「盡可能少匹配」,否則 .* 會吞掉後面的逗號與欄位,導致 group(3) 為空或錯誤。\" 代表字面雙引號,Regex 中同樣需轉義,故寫作 \\\"(代碼中字串字面量寫 \",編譯後 Regex 引擎見到 \")。Matcher.find() + 手動拼接 group(1) + "\"" + group(2) + "\"" + group(3),比 replaceAll 更可控,避免多次匹配誤替換。若 JSON 結構複雜(巢狀物件、陣列、值含逗號),強烈建議使用成熟 JSON 庫(Jackson, Gson, org.json)配合自定義反序列化器或預處理流,而非純正則硬解析。正則僅適用於結構固定、單一欄位修復的輕量場景。