- Java 中处理 JSON 的主流库
- Java 中的正则表达式基础
- 核心部分:JSON 与正则表达式的结合使用
- 一个完整的综合示例
- 最佳实践与注意事项
Java 中处理 JSON 的主流库
在 Java 中,没有内置的、原生的 JSON 库,最常用的是第三方库。

a) Jackson (推荐)
功能最强大、性能最好、社区最活跃的库,是 Spring Boot 等框架的默认选择。
-
核心模块:
jackson-databind: 核心库,用于在 JSON 和 Java 对象之间进行绑定。jackson-core: 底层 JSON 处理引擎。jackson-annotations: 提供注解,方便地控制序列化和反序列化行为。
-
Maven 依赖:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> <!-- 请使用最新版本 --> </dependency>
b) Gson
由 Google 开发,API 简单易用,非常适合小型项目或不需要复杂配置的场景。

- Maven 依赖:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> <!-- 请使用最新版本 --> </dependency>
c) org.json
一个轻量级的库,API 比较底层,需要手动操作 JSONObject 和 JSONArray。
- Maven 依赖:
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20251013</version> <!-- 请使用最新版本 --> </dependency>
Java 中的正则表达式基础
Java 通过 java.util.regex 包提供对正则表达式的支持。
核心类
Pattern: 正则表达式的编译表示,使用Pattern.compile(regex)方法创建。Matcher: 对输入字符串进行解释和匹配的引擎,由pattern.matcher(input)方法创建。PatternSyntaxException: 表示正则表达式模式中的语法错误。
常用方法示例
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexExample {
public static void main(String[] args) {
String text = "Hello my email is test.user-123@example.com and my phone is 123-456-7890.";
String emailRegex = "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b";
String phoneRegex = "\\d{3}-\\d{3}-\\d{4}";
// 1. 编译正则表达式
Pattern emailPattern = Pattern.compile(emailRegex);
Pattern phonePattern = Pattern.compile(phoneRegex);
// 2. 创建匹配器
Matcher emailMatcher = emailPattern.matcher(text);
Matcher phoneMatcher = phonePattern.matcher(text);
// 3. 查找并打印所有匹配项
System.out.println("Found emails:");
while (emailMatcher.find()) {
// group() 返回匹配到的子序列
System.out.println("- " + emailMatcher.group());
}
System.out.println("\nFound phones:");
if (phoneMatcher.find()) {
System.out.println("- " + phoneMatcher.group());
}
}
}
核心部分:JSON 与正则表达式的结合使用
这是最关键的部分,我们有两种需求场景:
在 JSON 字符串上直接使用正则表达式
当你有一个完整的 JSON 字符串,并且想从中提取符合特定模式的信息时(从日志文件中提取所有 JSON 对象中的特定字段)。

方法:
- 将整个 JSON 字符串视为一个普通的
String。 - 编写一个正则表达式来匹配你想要的部分。
- 使用
Pattern和Matcher进行查找。
示例: 从 JSON 字符串中提取所有 email 字段的值。
import java.util.regex.*;
public class RegexOnJsonString {
public static void main(String[] args) {
// 这是一个包含数组的 JSON 字符串
String jsonString = "{\"users\": [" +
"{\"id\": 1, \"name\": \"Alice\", \"email\": \"alice@example.com\"}," +
"{\"id\": 2, \"name\": \"Bob\", \"email\": \"bob.test@sub-domain.org\"}," +
"{\"id\": 3, \"name\": \"Charlie\", \"email\": \"charlie@example.co.uk\"}" +
"]}";
// 正则表达式解释:
// "email":\s* - 匹配 "email": 后面可能有空格
// " - 匹配开始的引号
// ([^"]+) - 这是一个捕获组,匹配一个或多个非引号字符,这就是我们要的邮箱
// " - 匹配结束的引号
String emailRegex = "\"email\":\\s*\"([^\"]+)\"";
Pattern pattern = Pattern.compile(emailRegex);
Matcher matcher = pattern.matcher(jsonString);
System.out.println("Extracted emails using regex on raw string:");
while (matcher.find()) {
// group(0) 是整个匹配项 ("email": "...")
// group(1) 是第一个捕获组 (邮箱地址)
System.out.println(matcher.group(1));
}
}
}
注意: 这种方法脆弱,JSON 结构稍有变化(比如字段顺序、空格变化),正则表达式就可能失效。不推荐用于解析复杂的 JSON,仅适用于简单的、格式固定的文本模式提取。
解析 JSON 后,在数据上使用正则表达式(推荐)
这是更健壮、更推荐的做法,先将 JSON 字符串解析成 Java 对象(如 List<Map>, 自定义 POJO, JSONArray 等),然后在结构化的数据上进行操作。
步骤:
- 使用 Jackson/Gson 等库将 JSON 字符串解析成 Java 对象。
- 遍历这个 Java 对象。
- 对每个需要验证的字符串字段,使用正则表达式进行匹配。
示例: 使用 Jackson 验证用户列表中的邮箱和手机号格式。
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class RegexAfterJsonParsing {
public static void main(String[] args) throws Exception {
String jsonString = "{\"users\": [" +
"{\"id\": 1, \"name\": \"Alice\", \"email\": \"alice@example.com\", \"phone\": \"111-222-3333\"}," +
"{\"id\": 2, \"name\": \"Bob\", \"email\": \"invalid-email\", \"phone\": \"444-555-6666\"}," +
"{\"id\": 3, \"name\": \"Charlie\", \"email\": \"charlie@example.co.uk\", \"phone\": \"1234567890\"}" +
"]}";
// 1. 使用 Jackson 解析 JSON
ObjectMapper mapper = new ObjectMapper();
// TypeReference 可以帮助我们处理复杂的泛型类型,如 List<Map>
List<Map<String, Object>> userList = mapper.readValue(jsonString, new TypeReference<List<Map<String, Object>>>() {});
// 预编译正则表达式以提高性能
Pattern emailPattern = Pattern.compile("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}$");
Pattern phonePattern = Pattern.compile("^\\d{3}-\\d{3}-\\d{4}$");
System.out.println("Validating user data after parsing:");
for (Map<String, Object> user : userList) {
String name = (String) user.get("name");
String email = (String) user.get("email");
String phone = (String) user.get("phone");
System.out.println("\nChecking user: " + name);
System.out.println(" Email: " + email);
System.out.println(" Phone: " + phone);
// 2. 在解析后的数据上使用正则表达式
if (email != null && !emailPattern.matcher(email).matches()) {
System.out.println(" -> [ERROR] Invalid email format!");
}
if (phone != null && !phonePattern.matcher(phone).matches()) {
System.out.println(" -> [ERROR] Invalid phone format!");
}
}
}
}
一个完整的综合示例
这个示例将展示一个更实际的应用:从 API 返回的 JSON 响应中,提取所有符合特定格式的日志 ID。
模拟的 JSON 响应:
{
"status": "success",
"data": {
"logs": [
{ "id": "log-abc-123", "level": "INFO", "message": "User logged in." },
{ "id": "error-def-456", "level": "ERROR", "message": "Failed to connect." },
{ "id": "log-ghi-789", "level": "DEBUG", "message": "Processing request." },
{ "id": "alert-jkl-012", "level": "WARN", "message": "Low memory warning." }
]
}
}
目标: 提取所有 id 字段中以 "log-" 开头,并且后面跟着三个字母和三个数字的 ID。
代码实现:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ComprehensiveExample {
public static void main(String[] args) {
String jsonResponse = "{\n" +
" \"status\": \"success\",\n" +
" \"data\": {\n" +
" \"logs\": [\n" +
" { \"id\": \"log-abc-123\", \"level\": \"INFO\", \"message\": \"User logged in.\" },\n" +
" { \"id\": \"error-def-456\", \"level\": \"ERROR\", \"message\": \"Failed to connect.\" },\n" +
" { \"id\": \"log-ghi-789\", \"level\": \"DEBUG\", \"message\": \"Processing request.\" },\n" +
" { \"id\": \"alert-jkl-012\", \"level\": \"WARN\", \"message\": \"Low memory warning.\" }\n" +
" ]\n" +
" }\n" +
"}";
// 1. 解析 JSON
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode rootNode = mapper.readTree(jsonResponse);
JsonNode logsNode = rootNode.path("data").path("logs");
// 2. 定义正则表达式
// 解释: ^log- - 以 "log-" 开头
// [a-zA-Z]{3} - 后面跟着3个字母
// -\d{3}$ - 再跟着一个 "-" 和3个数字,直到字符串结束
String logIdRegex = "^log-[a-zA-Z]{3}-\\d{3}$";
Pattern pattern = Pattern.compile(logIdRegex);
System.out.println("Extracting valid log IDs:");
// 3. 遍历 JSON 数组
for (JsonNode logNode : logsNode) {
String id = logNode.path("id").asText();
// 4. 对每个 ID 使用正则表达式进行匹配
Matcher matcher = pattern.matcher(id);
if (matcher.matches()) {
System.out.println(" - Found a valid log ID: " + id);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出:
Extracting valid log IDs:
- Found a valid log ID: log-abc-123
- Found a valid log ID: log-ghi-789
最佳实践与注意事项
-
优先选择 JSON 库: 永远不要用正则表达式来解析复杂的、结构不固定的 JSON,正则表达式是用于文本模式匹配的,而不是用于结构化数据解析的,使用 Jackson/Gson 等库是正确且健壮的做法。
-
预编译正则表达式: 如果你的正则表达式会被多次使用(例如在循环中),务必使用
Pattern.compile()预编译它,而不是在每次循环中都调用String.matches()或Pattern.matches(),这样可以显著提高性能。 -
正则表达式性能: 复杂的正则表达式(如包含回溯的)可能会很慢,在处理大量数据时要注意性能问题,可以使用
Pattern的compile方法传入Pattern.CASE_INSENSITIVE等标志来优化。 -
可读性与维护性: 正则表达式很难读懂,为复杂的正则表达式添加注释,或者将其定义为常量,可以提高代码的可维护性。
// 匹配标准的邮箱地址 private static final String EMAIL_REGEX = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}$"; private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX); -
转义: 在 Java 字符串中,反斜杠
\是一个转义字符,所以在写正则表达式时,你需要对它进行二次转义,匹配一个数字\d在 Java 字符串中要写成"\\d"。
希望这份详细的指南能帮助你掌握在 Java 中结合使用 JSON 和正则表达式!
