Java如何从指定表单字符串中提取目标键值对数据
问题说明
你需要解析一段存在键值对拼接、空值冗余问题的表单提交字符串,原始字符串定义如下:
String tmp = "Reason: decision=deny&denyReason=1&denyReasonSubcategory=PoorQuality&subCategoryComments=testsubCategoryComments=subCategoryComments=denyReasonSubcategory=ReviewAgainsubCategoryComments=hellosubCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryCommen=&subCategoryComments=&subCategoryComments=&subCategoryComments=&subCategoryComments=";
提取目标:
- 提取所有
denyReason的值存入数组,方便查询 - 提取
denyReasonSubcategory和对应非空subCategoryComments的配对,最终输出格式为PoorQuality:test; ReviewAgain:hello
你之前的实现存在三个明显问题,导致无法拿到正确结果:
- 键名拼写错误:代码中写的是
declineReason,和原始字符串的denyReason拼写不匹配 - 分割逻辑错误:仅按
&分割字符串,无法处理原始串中多个键值对直接拼接、无&分隔的长片段 - 缺少配对逻辑:仅判断键是否存在,没有建立子分类和对应评论的关联关系,也没有过滤大量空值的冗余字段
实现方案
核心思路是用正则全局匹配所有合法的键=值片段,不依赖&做分割,匹配时自动截断到下一个键名/&/字符串末尾,过滤空值后按业务逻辑做配对存储。
完整可运行代码如下:
import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class FormStringParser { public static void main(String[] args) { String tmp = "Reason: decision=deny&denyReason=1&denyReasonSubcategory=PoorQuality&subCategoryComments=testsubCategoryComments=subCategoryComments=denyReasonSubcategory=ReviewAgainsubCategoryComments=hellosubCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryComments=subCategoryCommen=&subCategoryComments=&subCategoryComments=&subCategoryComments=&subCategoryComments="; // 存储denyReason值的列表,支持多值查询 List<String> denyReasons = new ArrayList<>(); // 存储子分类和对应评论的配对,LinkedHashMap保证插入顺序 Map<String, String> subCategoryCommentMap = new LinkedHashMap<>(); // 正则规则:匹配三个目标键,捕获对应的值,遇到下一个键/&/字符串结尾就停止值匹配 Pattern kvPattern = Pattern.compile("(denyReason|denyReasonSubcategory|subCategoryComments)=([^&]*?)(?=(denyReason|denyReasonSubcategory|subCategoryComments)=|&|$)"); Matcher matcher = kvPattern.matcher(tmp); String currentMatchedSubCategory = null; while (matcher.find()) { String key = matcher.group(1); String value = matcher.group(2); // 跳过空值 if (value.isBlank()) { continue; } switch (key) { case "denyReason": denyReasons.add(value); break; case "denyReasonSubcategory": currentMatchedSubCategory = value; break; case "subCategoryComments": // 只给最近匹配到的、还未绑定评论的子分类配对 if (currentMatchedSubCategory != null) { subCategoryCommentMap.put(currentMatchedSubCategory, value); currentMatchedSubCategory = null; } break; } } // 验证输出 System.out.println("denyReason存储结果:" + denyReasons); // 拼接要求的格式字符串 StringBuilder formatResult = new StringBuilder(); for (Map.Entry<String, String> entry : subCategoryCommentMap.entrySet()) { if (formatResult.length() > 0) { formatResult.append("; "); } formatResult.append(entry.getKey()).append(":").append(entry.getValue()); } System.out.println("配对数据格式化结果:" + formatResult); } }
运行输出:
denyReason存储结果:[1] 配对数据格式化结果:PoorQuality:test; ReviewAgain:hello
方案适配点说明:
- 不依赖
&做分割,能正确识别所有拼接在一起的键值对,解决原始串格式不规范的问题 - 自动过滤所有空值的冗余
subCategoryComments字段,不会存入无效数据 - 配对逻辑保证每个子分类只绑定后面紧跟的第一个非空评论,不会被后续空字段覆盖
denyReason用List存储,支持多值场景,直接按索引即可查询对应值
内容的提问来源于stack exchange,提问作者FigureCodeOut
相关产品推荐
相关产品推荐

