繁体   English   中英

Stream Api - 用逗号分割排除嵌套逗号

[英]Stream Api - split by comma exclude nested commas

我有下面的代码,我在这里在线测试它。 也看过这个帖子 我不是最擅长正则表达式。 基本上我正在使用 stream API 吐出一个不包含内引号(双/单)的字符串。 它只是一个永远不会包含任何引号的纯字符串。 我正在尝试使用 stream API 将字符串按逗号拆分为键值对并将其放入 map。 但是,拆分也将requestparams=[id=4, isId=23]拆分为此isId=23], requestparams=[id=4 这一切都搞砸了。

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

class Main {
  public static void main(String[] args) {
    String dataPts = "requestparams=[id=4, isId=23], requestid=12345678, channel=BATCH";

    Map<String, String> reconstructedMap = Arrays.stream(dataPts.split(",")).map(s -> s.split("=",2)).collect(Collectors.toMap(s -> s[0], s -> s[1]));

    System.out.println(reconstructedMap);
  }
}

上述逻辑产生{ requestid=12345678, isId=23], requestparams=[id=4, channel=BATCH} [ ] 和里面的所有东西都应该保持原样。 我应该看到{requestparams=[id=4, isId=23], requestid=12345678, channel=BATCH}

我想出的解决方案是使用正则表达式从字符串中完全剪掉 requestparams=[id=4, isId=23] ,如下面的方法所示。 然后将其添加回最后的 map。 它看起来很乱而且不寻常。

Map<String,String> convertDataPtsFromStringToMap(String myData{ 
    Pattern pattern = Pattern.compile("requestparams=(.*?])");//value alone [id=4, isId=23]
    Matcher matcher = pattern.matcher(myData);
    String reqParamsValue = "[]";

    if(matcher.find()) {
        reqParamsValue = matcher.group(1);
        myData = myData.replaceAll("(requestparams.*?]),", "");//replace requestparams=[id=4, isId=23]
    }

    Map<String, String> reconstructedMap = Arrays.stream(dataPts.split(",")).map(s -> s.split("=",2)).collect(Collectors.toMap(s -> s[0], s -> s[1]));
    reconstructedMap.put("requestparams", reqParamsValue);//add back the requestparams and its value to the resulting map
    return reconstructedMap;
}

requestparams将是唯一带有 [ ] 的值并且不会更改,只是它必须在字符串中。 这就是为什么我可以将其剥离并放回原处。但是现在我的单元测试将要求该属性始终位于字符串中,这不是问题。 这似乎太多了。 寻找更优雅的解决方案。

有没有更好的方法使用 Streams-Api?

这是使用正式的 Java 正则表达式模式匹配器的一种方法:

String dataPts = "requestparams=[id=4, isId=23], requestid=12345678, channel=BATCH";
String pattern = "\\b([^=]+=(?:\\[[^]]+\\]|[^=,]+))(?:,\\s*|$)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(dataPts);
while (m.find()) {
    System.out.println(m.group(1));
}

这打印:

requestparams=[id=4, isId=23]
requestid=12345678
channel=BATCH

以下是正则表达式逻辑的解释:

\b
(                  capture the following
    [^=]+          a LHS key
    =              =
    (?:
        \[[^]]+\]  either a RHS term in square brackets (check for this first)
        |          OR
        [^=,]+     another term not in brackets
    )
)                  end capture
(?:,\\s*|$)        then match either comma followed by whitespace, or the end of the string

如果您想使用键/值填充 map,请使用:

String dataPts = "requestparams=[id=4, isId=23], requestid=12345678, channel=BATCH";
Map<String, String> map = new HashMap<>();
String pattern = "\\b([^=]+)=(\\[[^]]+\\]|[^=,]+)(?:,\\s*|$)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(dataPts);
while (m.find()) {
    map.put(m.group(1), m.group(2));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM