Regex-based parsing of a specifier for dice
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
5
down vote
favorite
In this android app, the user can enter (a subset of) roll20 notation to roll that many dice. Inputs will look like "4d6" at the simplest, but the user can also add or subtract numbers, and drop or keep the highest or lowest dice. I have implemented a class to do this parsing, with public methods for the resultant numbers.
Roll20NotationString.java
package com.mwapp.ron.fancydice;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Helper class to parse roll20 notation.
*/
public class Roll20NotationString dh
java regex dice
add a comment |Â
up vote
5
down vote
favorite
In this android app, the user can enter (a subset of) roll20 notation to roll that many dice. Inputs will look like "4d6" at the simplest, but the user can also add or subtract numbers, and drop or keep the highest or lowest dice. I have implemented a class to do this parsing, with public methods for the resultant numbers.
Roll20NotationString.java
package com.mwapp.ron.fancydice;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Helper class to parse roll20 notation.
*/
public class Roll20NotationString dh
java regex dice
add a comment |Â
up vote
5
down vote
favorite
up vote
5
down vote
favorite
In this android app, the user can enter (a subset of) roll20 notation to roll that many dice. Inputs will look like "4d6" at the simplest, but the user can also add or subtract numbers, and drop or keep the highest or lowest dice. I have implemented a class to do this parsing, with public methods for the resultant numbers.
Roll20NotationString.java
package com.mwapp.ron.fancydice;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Helper class to parse roll20 notation.
*/
public class Roll20NotationString dh
java regex dice
In this android app, the user can enter (a subset of) roll20 notation to roll that many dice. Inputs will look like "4d6" at the simplest, but the user can also add or subtract numbers, and drop or keep the highest or lowest dice. I have implemented a class to do this parsing, with public methods for the resultant numbers.
Roll20NotationString.java
package com.mwapp.ron.fancydice;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Helper class to parse roll20 notation.
*/
public class Roll20NotationString dh
java regex dice
edited Jun 20 at 16:12
Vogel612â¦
20.9k345124
20.9k345124
asked Jun 20 at 16:08
RWeb
263
263
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
1
down vote
Regex
The regex should be constructed in a way that makes it self-documenting. In particular, you should use named capture groups. Also, you can write the string literal over multiple lines, with // comments
at the end of each line if needed.
When using parentheses for grouping but not capturing, write (?:stuff)
rather than (stuff)
.
In my opinion, whitespace should be allowed before the drop/keep mode.
Class design
The InvalidNotationException
inner class should be static
. You aren't using three of its constructors, so you can omit all four constructors for now.
The parseString()
helper method should just be written directly in the constructor.
I suggest validating that the number of dice being dropped does not exceed the number of dice rolled.
A toString()
method, returning a canonical representation, would be helpful for future debugging.
Suggested solution
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Roll20NotationString k
add a comment |Â
up vote
0
down vote
Minor simplifications for the regex:
(d|k|dl|kh|dh|kl)
can be:
[dk][hl]?
Which makes it a bit easier to see what this does.
(\+|-)
is just
[+-]
This has the additional benefit of not needing to escape the +
Let me also echo what 200_success already stated about named capture-groups.
I personally prefer to not expose constructors that throw Exceptions. If something requires prevalidation, I prefer to expose a static factory method:
public static Roll20NotationString roll(String rollString) throws InvalidNotationException
Matcher matcher = grandRoll20RegexPattern.matcher(rollString);
if (!matcher.matches()) throw new InvalidNotationException();
// ...
Note that this allows you to drop the exception in favor of a "null object", in case you prefer that. This avoids the expensive creation of an exception and trades it for a nullcheck.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Regex
The regex should be constructed in a way that makes it self-documenting. In particular, you should use named capture groups. Also, you can write the string literal over multiple lines, with // comments
at the end of each line if needed.
When using parentheses for grouping but not capturing, write (?:stuff)
rather than (stuff)
.
In my opinion, whitespace should be allowed before the drop/keep mode.
Class design
The InvalidNotationException
inner class should be static
. You aren't using three of its constructors, so you can omit all four constructors for now.
The parseString()
helper method should just be written directly in the constructor.
I suggest validating that the number of dice being dropped does not exceed the number of dice rolled.
A toString()
method, returning a canonical representation, would be helpful for future debugging.
Suggested solution
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Roll20NotationString k
add a comment |Â
up vote
1
down vote
Regex
The regex should be constructed in a way that makes it self-documenting. In particular, you should use named capture groups. Also, you can write the string literal over multiple lines, with // comments
at the end of each line if needed.
When using parentheses for grouping but not capturing, write (?:stuff)
rather than (stuff)
.
In my opinion, whitespace should be allowed before the drop/keep mode.
Class design
The InvalidNotationException
inner class should be static
. You aren't using three of its constructors, so you can omit all four constructors for now.
The parseString()
helper method should just be written directly in the constructor.
I suggest validating that the number of dice being dropped does not exceed the number of dice rolled.
A toString()
method, returning a canonical representation, would be helpful for future debugging.
Suggested solution
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Roll20NotationString k
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Regex
The regex should be constructed in a way that makes it self-documenting. In particular, you should use named capture groups. Also, you can write the string literal over multiple lines, with // comments
at the end of each line if needed.
When using parentheses for grouping but not capturing, write (?:stuff)
rather than (stuff)
.
In my opinion, whitespace should be allowed before the drop/keep mode.
Class design
The InvalidNotationException
inner class should be static
. You aren't using three of its constructors, so you can omit all four constructors for now.
The parseString()
helper method should just be written directly in the constructor.
I suggest validating that the number of dice being dropped does not exceed the number of dice rolled.
A toString()
method, returning a canonical representation, would be helpful for future debugging.
Suggested solution
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Roll20NotationString k
Regex
The regex should be constructed in a way that makes it self-documenting. In particular, you should use named capture groups. Also, you can write the string literal over multiple lines, with // comments
at the end of each line if needed.
When using parentheses for grouping but not capturing, write (?:stuff)
rather than (stuff)
.
In my opinion, whitespace should be allowed before the drop/keep mode.
Class design
The InvalidNotationException
inner class should be static
. You aren't using three of its constructors, so you can omit all four constructors for now.
The parseString()
helper method should just be written directly in the constructor.
I suggest validating that the number of dice being dropped does not exceed the number of dice rolled.
A toString()
method, returning a canonical representation, would be helpful for future debugging.
Suggested solution
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Roll20NotationString k
answered Jun 20 at 21:10
200_success
123k14143399
123k14143399
add a comment |Â
add a comment |Â
up vote
0
down vote
Minor simplifications for the regex:
(d|k|dl|kh|dh|kl)
can be:
[dk][hl]?
Which makes it a bit easier to see what this does.
(\+|-)
is just
[+-]
This has the additional benefit of not needing to escape the +
Let me also echo what 200_success already stated about named capture-groups.
I personally prefer to not expose constructors that throw Exceptions. If something requires prevalidation, I prefer to expose a static factory method:
public static Roll20NotationString roll(String rollString) throws InvalidNotationException
Matcher matcher = grandRoll20RegexPattern.matcher(rollString);
if (!matcher.matches()) throw new InvalidNotationException();
// ...
Note that this allows you to drop the exception in favor of a "null object", in case you prefer that. This avoids the expensive creation of an exception and trades it for a nullcheck.
add a comment |Â
up vote
0
down vote
Minor simplifications for the regex:
(d|k|dl|kh|dh|kl)
can be:
[dk][hl]?
Which makes it a bit easier to see what this does.
(\+|-)
is just
[+-]
This has the additional benefit of not needing to escape the +
Let me also echo what 200_success already stated about named capture-groups.
I personally prefer to not expose constructors that throw Exceptions. If something requires prevalidation, I prefer to expose a static factory method:
public static Roll20NotationString roll(String rollString) throws InvalidNotationException
Matcher matcher = grandRoll20RegexPattern.matcher(rollString);
if (!matcher.matches()) throw new InvalidNotationException();
// ...
Note that this allows you to drop the exception in favor of a "null object", in case you prefer that. This avoids the expensive creation of an exception and trades it for a nullcheck.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Minor simplifications for the regex:
(d|k|dl|kh|dh|kl)
can be:
[dk][hl]?
Which makes it a bit easier to see what this does.
(\+|-)
is just
[+-]
This has the additional benefit of not needing to escape the +
Let me also echo what 200_success already stated about named capture-groups.
I personally prefer to not expose constructors that throw Exceptions. If something requires prevalidation, I prefer to expose a static factory method:
public static Roll20NotationString roll(String rollString) throws InvalidNotationException
Matcher matcher = grandRoll20RegexPattern.matcher(rollString);
if (!matcher.matches()) throw new InvalidNotationException();
// ...
Note that this allows you to drop the exception in favor of a "null object", in case you prefer that. This avoids the expensive creation of an exception and trades it for a nullcheck.
Minor simplifications for the regex:
(d|k|dl|kh|dh|kl)
can be:
[dk][hl]?
Which makes it a bit easier to see what this does.
(\+|-)
is just
[+-]
This has the additional benefit of not needing to escape the +
Let me also echo what 200_success already stated about named capture-groups.
I personally prefer to not expose constructors that throw Exceptions. If something requires prevalidation, I prefer to expose a static factory method:
public static Roll20NotationString roll(String rollString) throws InvalidNotationException
Matcher matcher = grandRoll20RegexPattern.matcher(rollString);
if (!matcher.matches()) throw new InvalidNotationException();
// ...
Note that this allows you to drop the exception in favor of a "null object", in case you prefer that. This avoids the expensive creation of an exception and trades it for a nullcheck.
answered Jun 21 at 8:22
Vogel612â¦
20.9k345124
20.9k345124
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f196903%2fregex-based-parsing-of-a-specifier-for-dice%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password