简体   繁体   中英

Regexp to split string in java

String s = "{key1:[1239,6783], key2:[323], key3:[{id: 61519, chart: false}], key4:[6,34,56], key5:[325432,545434]}"

Need to split the above string by using "," .

Expected:

s[0] = {key1:[1239,6783]  
s[1] = key2:[323]   
s[2] = key3:[{id: 61519,chart: false}]  
s[3] = key4:[6,34,56]  
s[4] = key5:[325432,545434]}  

Actual:

Splits by considering the commas which is present in the value pair too.  
s[0] = {key1:[1239  
s[1] = 6783]  and it's goes on...

Is it possible to do the above task using regexp and java? If Yes, please provide me the solution...

If this is a acceptable option, I would rather iterate over the matches with the following regex:

\w+\s*:\s*\[[^]]+\]

正则表达式可视化

Visualization by Debuggex


In Java:

String s = "{key1:[1239,6783], key2:[323], key3:[{id: 61519, chart: false}], key4:[6,34,56], key5:[325432,545434]}";
Pattern p = Pattern.compile("\\w+\\s*:\\s*\\[[^]]+\\]");
Matcher m = p.matcher(s);
while (m.find()) {
  System.out.println(m.group());
}

Prints:

key1:[1239,6783]
key2:[323]
key3:[{id: 61519, chart: false}]
key4:[6,34,56]
key5:[325432,545434]

Just split according to the comma which is followed by key:

string.split(",\\s*(?=\\w+:\\[)")

or

string.split(",\\s*(?=key\d+:\\[)")

You can use this lookahead based regex:

String[] toks = s.split(",(?![^\\[\\]]*\\])\\s*");
for (String tok: toks)
    System.out.printf("<%s>%n", tok);

Output:

<{key1:[1239,6783]>
<key2:[323]>
<key3:[{id: 61519, chart: false}]>
<key4:[6,34,56]>
<key5:[325432,545434]}>

RegEx Demo

Use a negative look ahead for the next bracket char being a close bracket:

String[] pairs = s.split(", *(?![^\\[\\]]*\\])");

If you want to go one step further and parse the key:value pairs into a map (in one line!):

 Map<String, String> map = Arrays.stream(s.replaceAll("^.|.$", "").split(", *(?![^\\[\\]]*\\])"))
    .map(p -> p.split(":")).collect(Collectors.toMap(a -> a[0], a -> a[1]));

You could keep going and recursively parse the values into String , String[] or Map<String, Object> , but then you'll have written you own json parser and you'd be better off using a library.


Some test code for the basic solution:

String s = "{key1:[1239,6783], key2:[323], key3:[{id: 61519, chart: false}], key4:[6,34,56], key5:[325432,545434]}";
Arrays.stream(s.split(", *(?![^\\[\\]]*\\])")).forEach(System.out::println);

Output:

{key1:[1239,6783]
key2:[323]
key3:[{id: 61519, chart: false}]
key4:[6,34,56]
key5:[325432,545434]}

Some test code for the to-map solution:

String s = "{key1:[1239,6783], key2:[323], key3:[{id: 61519, chart: false}], key4:[6,34,56], key5:[325432,545434]}";
Map<String, String> map = Arrays.stream(s.replaceAll("^.|.$", "").split(", *(?![^\\[\\]]*\\])"))
.map(p -> p.split(":")).collect(Collectors.toMap(a -> a[0], a -> a[1]));
System.out.println(map);

Output:

{key1=[1239,6783], key2=[323], key5=[325432,545434], key3=[{id, key4=[6,34,56]}

You could just use a simple alternate regex splitter( "], " )

String s = ""{key1:[1239,6783], key2:[323], key3:[{id: 61519, chart: false}], key4:[6,34,56], key5:[325432,545434]}"";

String[]tokens = s.split("], ");

System.out.println(Arrays.toString(tokens));

PS: This takes out the closing ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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