Reputation: 63
Recently I have been learning regular expressions, and I have been doing some complicated exercises.
I'm struggling to find a solution to this one:
Transform this:
"/country/usa/country/canada/state/florida/state/california/city/sandiego/city/paris"
to this :
group1 : country : usa, canada.
group2 : state : florida, california.
group3 : city : sandiego, paris
I tried this: (?:/\w+/(\w+))
the result I get is :
groupe1 : country : usa
groupe2 : country : canada.
groupe3 : state : florida,
groupe4 : state : california.
groupe5 : city : sandiego
groupe6 : city : paris
but I'm not getting the result I wanted.
I'm not really looking for a solution to copy and paste, but I want to understand why my regex is not working properly.
Upvotes: 1
Views: 54
Reputation: 6573
I'd probably just use a map for such a task - something like
String s = "/country/usa/country/canada/state/florida/state/california/city/sandiego/city/paris";
Pattern p = Pattern.compile("(?:/(\\w+)/(\\w+))");
Matcher m = p.matcher(s);
Map<String, List<String>> map = new LinkedHashMap<>();
while (m.find()) {
map.computeIfAbsent(m.group(1), k -> new ArrayList<>()).add(m.group(2));
}
System.out.println(map);
output:
{country=[usa, canada], state=[florida, california], city=[sandiego, paris]}
I used LinkedHashMap
to preserve the encounter order of the groups, as in your desired output.
Stream version:
Map<String, List<String>> map = m.results().collect(
Collectors.groupingBy(
r -> r.group(1),
LinkedHashMap::new,
Collectors.mapping(r -> r.group(2), Collectors.toList())));
Upvotes: 1