解析带分隔符的字符串并将其加载到地图中?
Parse a string with delimiters and load it in a map?
我有以下格式为 key1=value1, key2=value2
的字符串,我需要将其加载到地图 (Map<String, String>)
中作为 key=value
,所以我需要用逗号 [=15] 分隔=] 然后加载 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]);
}
我在这一行 holder.put(parts[0], parts[1]);
得到 java.lang.ArrayIndexOutOfBoundsException
并且它发生在这个字符串 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
鉴于您无法控制负载,您需要采取措施使 "illegal commas" 与您的“,”正则表达式不匹配。
Vampire 提供了一个很棒的正则表达式。由于我已经走上了手动解析的道路,所以我将在下面提供一个非正则表达式的解决方案。
另一种解决方案是通过逐字符迭代并保存子字符串来手动查找 parse/split 点。跟踪 "last comma-space" 直到到达 "next equals" 以确定是否拆分该逗号 - space 或不。
这里有一些代码演示了我要解释的内容。
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)));
}
}
正如您所说,您的密钥仅包含字母数字,以下可能是一个很好的拆分启发式方法:
payload.split("\s*,\s*(?=[a-zA-Z0-9_]+\s*=|$)");
这将根据可能的空格框逗号进行拆分,逗号后跟字符串末尾或字母数字键、可选的空格和等号。
我有以下格式为 key1=value1, key2=value2
的字符串,我需要将其加载到地图 (Map<String, String>)
中作为 key=value
,所以我需要用逗号 [=15] 分隔=] 然后加载 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]);
}
我在这一行 holder.put(parts[0], parts[1]);
得到 java.lang.ArrayIndexOutOfBoundsException
并且它发生在这个字符串 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
鉴于您无法控制负载,您需要采取措施使 "illegal commas" 与您的“,”正则表达式不匹配。
Vampire 提供了一个很棒的正则表达式。由于我已经走上了手动解析的道路,所以我将在下面提供一个非正则表达式的解决方案。
另一种解决方案是通过逐字符迭代并保存子字符串来手动查找 parse/split 点。跟踪 "last comma-space" 直到到达 "next equals" 以确定是否拆分该逗号 - space 或不。
这里有一些代码演示了我要解释的内容。
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)));
}
}
正如您所说,您的密钥仅包含字母数字,以下可能是一个很好的拆分启发式方法:
payload.split("\s*,\s*(?=[a-zA-Z0-9_]+\s*=|$)");
这将根据可能的空格框逗号进行拆分,逗号后跟字符串末尾或字母数字键、可选的空格和等号。