如何使用转义字符拆分或解析Java中的字符串

如何使用转义字符拆分或解析Java中的字符串,java,string,parsing,Java,String,Parsing,我有一个例子,我需要用各种转义字符拆分Java中的字符串。格式类似于: id:"description",id:"description",.... id:数字(整数) 描述:使用EscapeUtils.escapeJava(输入)转义的字符串,它可以包含任何 可读字符,包括:,,甚至“,它们将 转义到\” 因此,String.split方法似乎不合适,因为它可能会在、或:的描述中出现问题。我知道我可以编写一些运行良好的算法,这甚至是一个很好的测试驱动开发练习,但我想知道是否有一些懒惰的方法可

我有一个例子,我需要用各种转义字符拆分Java中的字符串。格式类似于:

id:"description",id:"description",....
id:数字(整数)
描述:使用EscapeUtils.escapeJava(输入)转义的字符串,它可以包含任何 可读字符,包括
甚至
,它们将 转义到
\”

因此,
String.split
方法似乎不合适,因为它可能会在
的描述中出现问题。我知道我可以编写一些运行良好的算法,这甚至是一个很好的测试驱动开发练习,但我想知道是否有一些懒惰的方法可以绕过它,并使用某种解析器来完成这类工作

我的另一种可能的方法是生成一个JSONArray,不要弄乱我不感兴趣的复杂性,但它将需要一个更多的库依赖项,我不相信它会包含在这个模块中


因此,我想要的是关于如何解决此类问题的想法(库、Java API等)。

听起来您的字符串应该与以下正则表达式匹配:

^(\d+:“([^”\\]\\\)*”(,(?!$)\$)+$
在这种情况下,您可以通过编写如下内容将零件提取到
映射中:

private static final Pattern TOTAL_STRING_PATTERN =
    Pattern.compile("^(\\d+:\"([^\"\\\\]|\\\\.)*\"(,(?!$)|$))+$");
private static final Pattern PARTIAL_STRING_PATTERN =
    Pattern.compile("(\\d+):\"((?:[^\"\\\\]|\\\\.)*)\"");

public Map<Integer, String> parse(final String input) {
    if(! TOTAL_STRING_PATTERN.matcher(input).matches()) {
        throw new IllegalArgumentException();
    }
    final Map<Integer, String> ret = new HashMap<Integer, String>();
    final Matcher m = PARTIAL_STRING_PATTERN.matcher(input);
    while(m.find()) {
        final Integer id = Integer.valueOf(m.group(1));
        final String description = StringEscapeUtils.unescapeJava(m.group(2));
        ret.put(id, description);
    }
    return Collections.unmodifiableMap(ret);
}
private静态最终模式总计\u字符串\u模式=
Pattern.compile(“^(\\d+:\”([^\“\\\]\\\\)*\”(,(?!$)\$)+$”;
私有静态最终模式部分字符串模式=
Pattern.compile(“(\\d+):\”((?:[^\\\\\\\]\124;\\\\\)*)\”;
公共映射解析(最终字符串输入){
如果(!TOTAL_STRING_PATTERN.matcher(input.matches()){
抛出新的IllegalArgumentException();
}
final Map ret=新的HashMap();
最终匹配器m=部分字符串模式匹配器(输入);
while(m.find()){
最终整数id=Integer.valueOf(m.group(1));
最终字符串描述=StringEscapeUtils.unescapeJava(m.group(2));
ret.put(标识、描述);
}
返回集合。不可修改映射(ret);
}

(您可能还希望检查标识符是否超出
int
的范围,以及同一标识符是否多次出现在字符串中,等等。并且您可能希望使您的模式在某些方面更加灵活,例如,允许冒号和逗号周围有空格。但上述情况应该是一个好方法开始。)

哇,这真的达到了我所期望的效果。我只需调整正则表达式以避开“\d”上的\“,然后它成功了,到目前为止,我还没有发现任何失败的案例,但必须用真实数据对其进行测试……我真的必须详细学习正则表达式,只在文本编辑器中使用它进行简单的搜索,但从未用于真正的解析。。。