tags:

views:

64

answers:

1

Hello,

I am trying to write a simple template engine to parse if statements.

<{if $value == true}>
    say hello
<{/if}>

I have written working code However, If I have multiple if statements in the file I am parsing then if grabs only the first and last if statement. For example.

<{if $value1 == true}>
    say hello
<{/if}>
...
<{if $value2 == true}>
    say hello
<{/if}>
...

The code parses and returns:

    say hello
<{/if}>
...
<{if $value2 == true}>
    say hello

Rather than just returning say hello.

Thanks for your help In advance the code is as follows:

    public class Templates {

        private static String escape(String value) {
            return value.replaceAll("\\$", "\\\\\\$");
        }

        public static String load(String name) {
            return load(name, null);
        }

        public static String load(String name, Map<String, String> parse) {

            String page = new Resources().getTextResource("lib/tpl/" + name);

            if (page == null) {
                return "The template, " + name + " was NOT FOUND.";
            }

            if (parse != null) {
                Iterator it = parse.entrySet().iterator();

                while (it.hasNext()) {

                    Map.Entry entry = (Map.Entry) it.next();
                    String key = (String) entry.getKey();
                    String value = (String) entry.getValue();

                    value = escape(value); // Prevents java exception. Can't deal with $

                    page = page.replaceAll("\\<\\{\\$" + key + "\\}\\>", value);


                }

                Pattern ptrn = Pattern.compile("\\<\\{if \\$([a-z]+)\\s*(==|!=|eq|neq|or|and)\\s*(\\w+)\\}\\>(\\p{ASCII}+)\\<\\{/if\\}\\>");

                Matcher mtch = ptrn.matcher(page);

                System.out.println("\n\n\n");

                while(mtch.find()) {

                    System.out.println("Key is: " + mtch.group(1));
                    //System.out.println("Key: " + dateMatcher.group(2));
                    System.out.println("Value is: " + mtch.group(3));
                    System.out.println("Data is: " + mtch.group(4));

                    if(parse.get(mtch.group(1)).equals(mtch.group(3))) {
                        System.out.println("\n\n\nREPLACE");
                        page = page.replaceAll(ptrn.pattern(), escape(mtch.group(4)));
                    } else {
                        //dateMatcher.appendReplacement(page, "");
                        System.out.println("\n\n\nREMOVE - " + ptrn.pattern());
                        page = page.replaceAll(ptrn.pattern(), "");
                    }

                }

                System.out.println("\n\n\n");


            }
            return page;


}
}
+2  A: 

This might be due to greedy nature.

Try this,

(\\p{ASCII}+?) instead of (\\p{ASCII}+)

Marimuthu Madasamy
I see, thanks http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/java/util/regex/Pattern.html
James Moore
That is an ancient page (1.4.x). Here's the current version: http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html
seanizer
Beware that if you have nested if statements you can't use a regex to parse the template.
Kwebble