使用分隔符解析字符串并将其加载到地图中?

时间:2016-05-24 00:22:46

标签: java regex string split guava

我有以下格式为key1=value1, key2=value2的字符串,我需要将其作为(Map<String, String>)加载到地图key=value中,因此我需要在逗号,上拆分然后加载cossn作为密钥,0加上其值。

String payload = "cossn=0, abc=hello/=world, Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";

HashMap<String, String> holder = new HashMap();
String[] keyVals = payload.split(", ");
for(String keyVal:keyVals) {
  String[] parts = keyVal.split("=",2);
  holder.put(parts[0], parts[1]);
}   

我在此行java.lang.ArrayIndexOutOfBoundsException收到holder.put(parts[0], parts[1]);,并且它正在发生此字符串Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36的bcoz,因为它在值KHTML, like Gecko中有一个额外的逗号。

我该如何解决这个问题?通常,在地图中加载后,下面应该是我的键和值。

Key         Value
cossn       0
abc         hello/=world
Agent       Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36

2 个答案:

答案 0 :(得分:4)

正如你所说,你的密钥只包含字母数字,以下可能是一个很好的分裂启发式方法:

payload.split("\\s*,\\s*(?=[a-zA-Z0-9_]+\\s*=|$)");

可能会拆分空白框架逗号,后面跟着字符串结尾或字母数字键,可选空格和等号。

答案 1 :(得分:0)

鉴于您无法控制有效负载,您需要做一些事情以使“非法逗号”与您的“,”正则表达式不匹配。

吸血鬼提供了很好的正则表达。由于我已经走了人工解析的道路,我将在下面提供一个非正则表达式解决方案。

另一种解决方案是通过逐个字符迭代并保存子字符串来手动查找解析/拆分点。跟踪“最后一个逗号空间”,直到达到“下一个等于”,以确定是否在该逗号空间上拆分。

以下是一些代码,演示了我要解释的内容。

import java.util.Arrays;

public class ParseTest {

    static String payload = "cossn=0, abc=hello/=world, Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";

    public static void main(String[] args) {
        int lastCommaSpace = -2;
        int beginIndex = 0;

        // Iterate over string
        // We are looking for comma-space pairs so we stop one short of end of
        // string
        for (int i = 0; i < payload.length() - 1; i++) {
            if (payload.charAt(i) == ',' && payload.charAt(i + 1) == ' ') {
                // This is the point we want to split at
                lastCommaSpace = i;
            }
            if (payload.charAt(i) == '=' && lastCommaSpace != beginIndex - 2) {
                // We've found the next equals, split at the last comma we saw
                String pairToSplit = payload.substring(beginIndex, lastCommaSpace);
                System.out.println("Split and add this pair:" + Arrays.toString(pairToSplit.split("=", 2)));
                beginIndex = lastCommaSpace + 2;
            }
        }
        // We got to the end, split the last one
        String pairToSplit = payload.substring(beginIndex, payload.length());
        System.out.println("Split and add this pair:" + Arrays.toString(pairToSplit.split("=", 2)));
    }

}