Divide an alphanumeric string into a map of numbers and strings Below is a bit of code which divides an alphanumeric string to a map of numbers and strings (assume numbers are single digits and non-repeating).

Example input:

String alphaNumericStr = "1abcdef2xyz9aaa6xxx";        


Output:

Map&lt;Integer, String&gt; map = {1=abcdef, 2=xyz, 9=aaa, 6=xxx}


This is the code i wrote. While it gets the work done, this does not look like a clean solution to me. How can I make this better?

    String alphaNumericStr = "1abcdef2xyz9aaa6xxx";

    Map&lt;Integer, String&gt; map = new LinkedHashMap&lt;Integer, String&gt;();

    Character key = null;
    StringBuffer s = new StringBuffer();

    for (int i = 0; i &lt; alphaNumericStr.length(); i++) {
        Character c = alphaNumericStr.charAt(i);

        if (Character.isDigit(c)) {
            if (s.length() &gt; 0) {
                map.put(Character.getNumericValue(key), s.toString());
                s = new StringBuffer();

            }
            key = c;

        } else {
            s.append(c);
            if (i == alphaNumericStr.length() - 1) {
                map.put(Character.getNumericValue(key), s.toString());
            }
        }
    }

    System.out.println(map);
You can use this regex (\d+)(\D+) which will match two groups, one is to match the number and the second to match the non digit part, beside If you are using Java 9+ Pattern, you can use simply :

String input = "1abcdef2xyz9aaa6xxx";
String regex = "(\\d+)(\\D+)";

Map&lt;Integer, String&gt; map = Pattern.compile(regex)
        .matcher(input)
        .results()
        .collect(Collectors.toMap(
                m -&gt; Integer.parseInt(m.group(1)), m -&gt; m.group(2)
        ));

System.out.println(map);




Result 

{1=abcdef, 2=xyz, 9=aaa, 6=xxx}




If you are using Java 8 or lower, you can use :

String alphaNumericStr = "1abcdef2xyz9aaa6xxx";
String regex = "(\\d+)(\\D+)";
Matcher matcher = Pattern.compile(regex).matcher(alphaNumericStr);

Map&lt;Integer, String&gt; map = new HashMap&lt;&gt;();
while (matcher.find()) {
    map.put(Integer.parseInt(matcher.group(1)), matcher.group(2));
}
System.out.println(map);




But you will lose some information if the input contain the same number, in this case I would like to create a class which hold a number and a String and use a list in this case instead.