Any good Regexp tutorials?

Not game related- hence it being in this forum- but every time I read anything by any kind of programmer who knows anything about anything they always rave about the life-transforming power or Regexps and how they will improve every aspect of your life if you even think about them. I’ve been thinking about them and what I’ve thought is that I have no idea how to use them well.

Can anyone suggest any good resources for learning about them? Ideally stuff that takes you from basic to advanced without a) assuming you’re a moron or b) jumping from incredibly simple to awesomely complex without a word in between. I realise that’s a heck of a lot to ask…

Start with the javadocs http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html

Then google from there.
e.g.
http://www.regular-expressions.info/tutorial.html

Keep in mind that often the regular expression you see printed have a backslash character and so when you enter then in java source code as a String you must escape the backslash by using a double backslash… this can make the regex in the code hard to read when compared to the ‘real’ expression.

e.g. \d matches a digit, but as a Java string it must be “\d”

And if I’m escaping the backslash for a literal I need “\\” ?

Yes, that’s covered in the second link above.

I wrote a small Java regex guide which I refer to a lot when doing java regex (especially since I seem to do it fairly sporadically ). It does NOT teach you much about regular expressions, but does help one take that knowledge and apply it to java (so useful if you already know about regex, or a reading non-java tutorial about it).

http://tanksoftware.com/tutes/article-regexprimer.pdf

It is designed to be used with the Pattern javadoc’s which give you all the info about character classes etc. that you need.

Will.

How’s this for use of regex?
Can anyone improve this further?
I’m still not great at using regex.


private void convertParamToObj(String word)
      {
            Scanner scanner = new Scanner(word);
            
            if(Pattern.matches("WORLD = \\d*, \\d*, \\d*, \\d*;",  word))
            {
                  String type = "\\d+";
                  int row = Integer.parseInt(scanner.findInLine(type));
                  int cols = Integer.parseInt(scanner.findInLine(type));
                  int width = Integer.parseInt(scanner.findInLine(type));
                  int height = Integer.parseInt(scanner.findInLine(type));
                  
                  world = new World(row, cols, width, height);
            }
            
            scanner.close();
      }

[quote]How’s this for use of regex?
Can anyone improve this further?
[/quote]
I recommend using the Matcher class instead:

Matcher m = Pattern.compile("WORLD = (\\d+), (\\d+), (\\d+), (\\d+);").matcher(word);
if(m.matches())
{
      int row = Integer.parseInt(m.group(1));
      int cols = Integer.parseInt(m.group(2));
      int width = Integer.parseInt(m.group(3));
      int height = Integer.parseInt(m.group(4));
      world = new World(row, cols, width, height);
}

I’m with cfmdobbie, but note also that you used an inconsistent pattern,

For the row you used the asterisk - meaning 0 or more, for the field matching you used the plus - meaning 1 or more.

If your input can have an empty field e.g. 1, , 3, 4 then the asterisk * is required in both places (cfmdobbie’s code would need a tweak). You can also be a bit more resilient in terms of dealing with white-space.

“(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)”

That would allow spaces or tabs before or after the commas, and the numbers could be omitted entirely if you wanted the concept of an empty field. (Just remember that if you allow empty fields the group could be an empty string and therefore it won’t parse as an Integer.)

Thanks guys. Is the regex fast enough to use in a game during runtime?

Currently I’m using it to load maps from plain text files.

swpalmer: I rather assumed that that was an oversight - those values all looked rather important to me! :wink:

[quote]Thanks guys. Is the regex fast enough to use in a game during runtime?

Currently I’m using it to load maps from plain text files.
[/quote]
Cripes, yeah. Sitting next to a bunch of disk I/O you really won’t notice it at all. ::slight_smile:

However, like any behind-the-scenes String-processing code, I’d avoid using it in a render-loop.

Being a general solution it will be a bit slower than if you optimized something to do exactly what you want and only that. (e.g. indexOf() on a string is faster than finding a substring using a regex)

You can compile the pattern once and save it to avoid that cost throughout the game… but really you should just profile the part that is using it to see if it really matters or not.

[quote]Thanks guys. Is the regex fast enough to use in a game during runtime?

Currently I’m using it to load maps from plain text files.
[/quote]
Pattern’s static factory method “compiles” the regular expression in a state machine. Once compiled, a regular expression is quite fast, taking character as input event and switching from state to state. So you can use a regex in a loop very efficiently, but try to compile it outside of the loop.