Regex-based parsing of a specifier for dice

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite
1












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






share|improve this question



























    up vote
    5
    down vote

    favorite
    1












    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






    share|improve this question























      up vote
      5
      down vote

      favorite
      1









      up vote
      5
      down vote

      favorite
      1






      1





      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






      share|improve this question













      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








      share|improve this question












      share|improve this question




      share|improve this question








      edited Jun 20 at 16:12









      Vogel612♦

      20.9k345124




      20.9k345124









      asked Jun 20 at 16:08









      RWeb

      263




      263




















          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





          share|improve this answer




























            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.






            share|improve this answer





















              Your Answer




              StackExchange.ifUsing("editor", function ()
              return StackExchange.using("mathjaxEditing", function ()
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              );
              );
              , "mathjax-editing");

              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "196"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              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






























              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





              share|improve this answer

























                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





                share|improve this answer























                  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





                  share|improve this answer













                  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






                  share|improve this answer













                  share|improve this answer



                  share|improve this answer











                  answered Jun 20 at 21:10









                  200_success

                  123k14143399




                  123k14143399






















                      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.






                      share|improve this answer

























                        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.






                        share|improve this answer























                          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.






                          share|improve this answer













                          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.







                          share|improve this answer













                          share|improve this answer



                          share|improve this answer











                          answered Jun 21 at 8:22









                          Vogel612♦

                          20.9k345124




                          20.9k345124






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              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













































































                              Popular posts from this blog

                              Greedy Best First Search implementation in Rust

                              Function to Return a JSON Like Objects Using VBA Collections and Arrays

                              C++11 CLH Lock Implementation