将key = value的String解析为Map

我正在使用一个API给我一个XML,我需要从一个标签获取一个实际上是字符串的地图。 例:

Billable=7200,Overtime=false,TransportCosts=20$ 

我需要

 ["Billable"="7200","Overtime=false","TransportCosts"="20$"] 

问题是字符串是完全动态的,所以,它可能就像

 Overtime=true,TransportCosts=one, two, three Overtime=true,TransportCosts=1= 1,two, three,Billable=7200 

所以我不能用逗号分割,然后用等号分开。 是否可以使用正则表达式将类似字符串转换为地图?

到目前为止我的代码是:

 private Map getAttributes(String attributes) { final Map attr = new HashMap(); if (attributes.contains(",")) { final String[] pairs = attributes.split(","); for (String s : pairs) { if (s.contains("=")) { final String pair = s; final String[] keyValue = pair.split("="); attr.put(keyValue[0], keyValue[1]); } } return attr; } return attr; } 

先感谢您

你可以用

 (\w+)=(.*?)(?=,\w+=|$) 

请参阅正则表达式演示 。

细节

  • (\w+) – 第1组:一个或多个单词字符
  • = – 一个等号
  • (.*?) – 第2组:除了换行符之外的任何零个或多个字符,尽可能少
  • (?=,\w+=|$) – 一个正向前瞻,需要一个,然后是1 +字的字符,然后= ,或者字符串的结尾立即在当前位置的右边。

Java代码:

 public static Map getAttributes(String attributes) { Map attr = new HashMap<>(); Matcher m = Pattern.compile("(\\w+)=(.*?)(?=,\\w+=|$)").matcher(attributes); while (m.find()) { attr.put(m.group(1), m.group(2)); } return attr; } 

Java测试 :

 String s = "Overtime=true,TransportCosts=1= 1,two, three,Billable=7200"; Map map = getAttributes(s); for (Map.Entry entry : map.entrySet()) { System.out.println(entry.getKey() + "=" + entry.getValue()); } 

结果:

 Overtime=true Billable=7200 TransportCosts=1= 1,two, three 

我注意到的第一件事是分隔符不容易用你给出的数据识别,但看起来可识别的是用逗号后跟大写字母分隔每个字段。

这允许使用String.replaceAll("(?<=,)([AZ])", ",$1")将分隔符更改为可以使用正则表达式轻松识别的方法。 现在,您将拥有一个分隔符,您可以识别(,,)并拆分数据以在需要时插入引号。

就像是:

 public class StackOverflow { public static void main(String[] args) { String [] data = { "Overtime=true,TransportCosts=one, two, three", "Overtime=true,TransportCosts=1= 1,two, three,Billable=7200" }; for (int i = 0; i < data.length; i++) { data[i] = data[i].replaceAll("(?<=,)([AZ])", ",$1"); String[] pieces = data[i].split(",,"); for (int j = 0; j < pieces.length; j++) { int equalIndex = pieces[j].indexOf("="); StringBuilder sb = new StringBuilder(pieces[j]); // Insert quotes around the = sign sb.insert(equalIndex, "\""); sb.insert(equalIndex + 2, "\""); // Insert quotes at the beginning and end of the string sb.insert(0, "\""); sb.append("\""); pieces[j] = sb.toString(); } // Join the pieces back together delimited by a comma data[i] = String.join(",", pieces); System.out.println(data[i]); } } } 

结果

 "Overtime"="true","TransportCosts"="one, two, three" "Overtime"="true","TransportCosts"="1= 1,two, three","Billable"="7200" 

另类,恕我直言更简单的正则表达式: ([^,]+=[^=]+)(,|$)

([^,]+=[^=]+) →组:除逗号外的任何内容,后跟1等号,后跟除等号后的任何内容…
(,|$) →…用逗号或行尾分隔

测试:

 public static void main(String[] args) { Pattern pattern = Pattern.compile("([^,]+=[^=]+)(,|$)"); String test1 = "abc=def,jkl,nm=ghi,egrh=jh=22,kdfka,92,kjasd=908@0982"; System.out.println("Test 1: "+test1); Matcher matcher = pattern.matcher(test1); while (matcher.find()) { System.out.println(matcher.group(1)); } System.out.println(); String test2 = "Overtime=true,TransportCosts=1= 1,two, three,Billable=7200"; System.out.println("Test 2: "+test2); matcher = pattern.matcher(test2); while (matcher.find()) { System.out.println(matcher.group(1)); } } 

输出:

Test 1: abc=def,jkl,nm=ghi,egrh=jh=22,kdfka,92,kjasd=908@0982
abc=def,jkl
nm=ghi
egrh=jh=22,kdfka,92
kjasd=908@0982

Test 2: Overtime=true,TransportCosts=1= 1,two, three,Billable=7200
Overtime=true
TransportCosts=1= 1,two, three
Billable=7200