VB.NET提取两字符串间子串返回错误或值异常问题排查
解决非标准键值对字符串解析问题(第二个字段取值异常)
我之前也踩过这种无分隔符键值对字符串的坑,尤其是遇到时间字段带冒号的情况,很容易把字段边界搞混。结合你给出的示例字符串,帮你梳理下问题原因和解决办法:
问题根源分析
你的字符串是键名+值+键名+值的连续拼接格式,没有字段分隔符,而且时间字段(buyTime/untilTime)里本身包含冒号。如果之前用了split(":")这种简单方式拆分,或者正则没有明确字段边界,就会导致第二个字段(比如Amount)的取值包含后面的内容(比如5.00Accounts),自然不符合预期。
正确解析步骤
1. 先拆分单个用户条目
首先用EndBREAK作为分隔符,把整个长字符串拆分成独立的用户数据条目:
String rawData = "你的原始长字符串"; String[] userEntries = rawData.split("EndBREAK");
2. 用带边界的正则提取字段值
针对每个条目,使用正向预查的正则表达式来精准匹配每个字段的值,确保只取到当前键名到下一个键名(或条目结尾End)之间的内容。
推荐封装一个通用提取方法,避免重复写正则:
private String extractValue(String entry, String key) { // 列出所有可能的键名,用于匹配字段边界 String[] allKeys = {"UserToken", "Amount", "Accounts", "buyTime", "untilTime", "End"}; StringBuilder nextKeyPattern = new StringBuilder(); for (String k : allKeys) { if (!k.equals(key)) { // 用Pattern.quote转义特殊字符,避免正则冲突 nextKeyPattern.append(Pattern.quote(k)).append("|"); } } if (nextKeyPattern.length() > 0) { nextKeyPattern.deleteCharAt(nextKeyPattern.length() - 1); } // 构建正则:匹配键名+冒号,然后捕获直到下一个键名冒号或End的内容 String regex = Pattern.quote(key) + ":(.*?)(?=(" + nextKeyPattern + "):|End)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(entry); if (matcher.find()) { return matcher.group(1).trim(); } return ""; }
3. 解析所有字段并传入ListView
循环处理每个条目,提取所有字段后存入数据列表,再传给ListView的适配器:
List<UserData> userList = new ArrayList<>(); for (String entry : userEntries) { if (entry.trim().isEmpty()) continue; // 跳过空条目 String token = extractValue(entry, "UserToken"); String amount = extractValue(entry, "Amount"); // 这里就能拿到正确的5.00/25.00了 String accounts = extractValue(entry, "Accounts"); String buyTime = extractValue(entry, "buyTime"); String untilTime = extractValue(entry, "untilTime"); userList.add(new UserData(token, amount, accounts, buyTime, untilTime)); } // 把userList绑定到ListView适配器 // 示例适配器代码(根据你的项目调整) ArrayAdapter<UserData> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, userList); listView.setAdapter(adapter);
4. 数据实体类(可选)
为了更清晰地管理数据,可以定义一个简单的实体类:
class UserData { String token; String amount; String accounts; String buyTime; String untilTime; public UserData(String token, String amount, String accounts, String buyTime, String untilTime) { this.token = token; this.amount = amount; this.accounts = accounts; this.buyTime = buyTime; this.untilTime = untilTime; } // 重写toString方法,让ListView显示你需要的内容 @Override public String toString() { return "Token: " + token + ", Amount: " + amount; } }
为什么这个方法有效?
- 拆分条目时用
EndBREAK确保每个条目是独立的用户数据; - 正则的正向预查
(?=...)会精准匹配下一个键名的开头,不会把后面的字段内容包含进来; - 用
Pattern.quote()转义键名,避免键名里的特殊字符干扰正则匹配。
内容的提问来源于stack exchange,提问作者xored
相关产品推荐
相关产品推荐

