Using regular expression to find renderer from size(...)

In GUI Builder I use a regular expression (originally created by by Florian Jenett) to parse the size() statement e.g.

// examples of calls to size
size(480,320);
size(320,240,OPENGL);

Now the regular expression shown below can be used to get 3 groups

Group 0 the full expressions e.g. size(320,240,OPENGL);

Group 1 the width e.g. 320

Group 2 the height e.g. 240

Unfortunately it doesn't get the renderer e.g. OPENGL

Now all these group values are retrieved as String(s), so I could extract it from Group 0 using the String class methods but since I am using a regular expression for the width and height I would like to use that.

Extract from GUI Builder source code

// The pattern is used to find the width and height from the size() statement
// I have shamelessly taken this code from ProcessingJS by florian jenett
// because it is way beyond my knowledge of regular expressions. 
String SK_SIZE = "(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+),?\\s*([^\\)]*)\\s*\\)";

Can anyone modify it to get the renderer (if one is specified)?

Answers

  • Mmm, actually, the expression you show almost work already, no?

    String SK_SIZE = "(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+),?\\s*([^\\)]*)\\s*\\)";
    
    String size1 = "size(480,320);";
    String size2 = "size(480, 320, OPENGL);";
    String size3 = "size   (  480 ,   320  ,P3D);";
    String size4 = "size(400, 400, PDF, \"filename.pdf\");";
    
    void setup()
    {
    p(match(size1, SK_SIZE));
    p(match(size2, SK_SIZE));
    p(match(size3, SK_SIZE));
    p(match(size4, SK_SIZE));
    exit();
    }
    
    void p(String[] ra)
    {
      for (String r : ra)
      {
        print("[" + r + "]");
      }
      println();
    }
    

    Needs some adjustments, I will look into it.

  • edited July 2014 Answer ✓
    String SK_SIZE = "(?:\\s*;?\\s*)size\\s*\\(\\s*(\\w+)\\s*,\\s*(\\w+)\\s*(?:,\\s*(\\w+)\\s*.*?)?\\)";
    
    String size1 = "    size(480,320);";
    String size2 = "size(480, 320, OPENGL);";
    String size3 = "size   (  480 ,   320  ,P3D)  ;  ";
    String size4 = "size(displayWidth, displayHeight, PDF, \"filename.pdf\");";
    // Would need more work! But should be discouraged anyway...
    String size5 = "size(400 * 2, 400 / 2, PDF, \"filename.pdf\");";
    
    void setup()
    {
    p(match(size1, SK_SIZE));
    p(match(size2, SK_SIZE));
    p(match(size3, SK_SIZE));
    p(match(size4, SK_SIZE));
    p(match(size5, SK_SIZE));
    exit();
    }
    
    void p(String[] ra)
    {
      if (ra == null)
      {
        println("Not matching");
        return;
      }
      for (String r : ra)
      {
        print("[" + r + "]");
      }
      println();
    }
    
  • It works perfectly for me. Not sure if the semi-colon should be a part of this...

    Y'know, if you are sure about the format you're using (for instance, you will always use size(320, 240, OPENGL) with not a single character different), you can easily trim off half the characters in the regex.

  • Answer ✓

    If one line in your code looks exactly like what I showed above, with all other operations, method calls, etc. on different lines, this regex will work just fine:

    import java.util.regex.*;
    
    String sizes = "size(320, 240, OPEN)";
    String regex = "size\\((\\d+), (\\d+),?\\s*(\\w*)\\)";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(sizes);
    if(m.matches()) {
      println(m.group(3));
    }
    

    I've mostly made the move towards Java in the past year, so I wouldn't have known of Processing's own matcher.

    But if you don't know how you, or someone else, is going to write their size() method call, the fjen's is just fine.

  • Hi guys thanks for responding you know what its like when you hit a problem sometimes you get tunnel vision and make assumptions.

    Well I took and combined your code and created a simple sketch to test the regex. In the process I discovered that the regex works just fine and it was my mistake. If I had thought about it more I should have realised that the regex worked because it did in processing.js :\">

    Although groupCount returned 3 I assumed that this meant there were just three groups with indices 0-2 (similar to arrays). In fact Group 0 is not included in groupCount so the groups were numbered 0-3

    So again thanks to both of you and I include the sketch code I used for testing in case it can be of value to others wanting to use regular expressions.

    import java.util.regex.*;
    
    String SK_SIZE = "(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+),?\\s*([^\\)]*)\\s*\\)";
    
    Pattern p;
    Matcher m;
    
    String[] sizes = {
      "public void size(480,320) ;", 
      "public  void  size  ( 480 , 320 ) ;", 
      "void size(480, 320, OPENGL);", 
      "void  size   (  480 ,   320  ,P3D);", 
      "void    size(400, 400, PDF, \"filename.pdf\");"
    };
    
    public void setup() {
      p = Pattern.compile(SK_SIZE);
      for (String s : sizes)
        performRegex(s, p);
      exit();
    }
    
    public void performRegex(String s, Pattern p) {
      m = p.matcher(s);
      if (m.find()) {
        for (int i = 0; i<= m.groupCount (); i++) 
          System.out.print("'" + m.group(i) + "'  ");
        println();
      } else {
        System.out.println("No match found for '" + s + "'");
      }
      println("----------------------------------------------------");
    }
    
Sign In or Register to comment.