kml2019
kml2019

Reputation: 63

Handle complicated regex

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

Answers (1)

Hulk
Hulk

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

Related Questions