2

I'm trying to parse an input string of type "move 2 up;1 right;1 down" using a regex, but I can't seem to figure out how to get all groups of commands while ignoring the "move" keyword.

My regex is:

(?:\bmove\b) ((?<amount>[1-6]) (?<direction>(\bup\b|\bright\b|\bdown\b|\bleft\b))(?:;?))+ 

and my Java code is this:

String str = "move 1 right;2 left;"; String regex = "(?:\\bmove\\b) ((?<amount>[1-6]) (?<direction>(\\bup\\b|\\bright\\b|\\bdown\\b|\\bleft\\b))(?:;?))+"; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher match = pattern.matcher(str); while (match.find()) { String group = match.group(1); System.out.println(group); } 

In the loop I would like to get the first command as "1 right" and the second as "2 left". With the regex that I have now I only get the "2 left;". There are some examples of input here: https://regex101.com/r/Fg0hk3/3.

How do I fix my regex?


Ended up using 2 regex patterns, one for the full match and one for the tokens:

Full match:

(?:\bmove\b) ((?<amount>[1-6]) (?<direction>(\bup\b|\bright\b|\bdown\b|\bleft\b))(?:;?))+ 

Tokens:

(?<amount>[1-6]) (?<direction>(?:\bup\b|\bright\b|\bdown\b|\bleft\b)) 
1

1 Answer 1

4

The simplest way to do this is to create a regular expression to match only the part you need (number and direction) without "move" or the semicolons. Then match it to the string and add all groups to a list.

String str = "move 55 up;2 right;100 down;8 left"; String regex = "(\\d+ (?:up|down|left|right))"; List<String> matches = new ArrayList<String>(); Matcher m = Pattern.compile(regex).matcher(str); while (m.find()) { matches.add(m.group()); } System.out.println(matches); // Output: [55 up, 2 right, 100 down, 8 left] 
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, this is a good way to get all the groups I need, but if I want to validate the whole input string do I need to use a second regex (like my initial one)?
It's impossible to match the entire string because regular expressions in Java don't support repeating captured groups. If you try, it will only match the first and last captured groups and not all of them. See this example and this question for more info.
Ok, so using 2 regex patterns, one for the full match and one for the groups seems to have done the trick. Thanks Adam!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.