Hi,

We recently upgraded our Jinja1 to Jinja2 and only in the process
noticed that the test "matching" is gone.
How silly.

You don't even bother to mention that in the documentation titled
"Switching from other Template Engines",
in Jinja1 section.

Is it possible to have regex support in future releases, without using
extensions?
I have written simple and powerful extensions myself, for adding a
regex "sub" and
"escape" filters, and a regex "match" test. Please see the
documentation below.
Note that most of the text is almost copy-paste from the Python re
module documentation.

I would be very happy to see these simple but powerful re features to
be added
in future Jinja2 releases. You may use my code however you want.


** test re_match(pattern[, flags])
If regex pattern matches the string, return True.
Otherwise return False. The optional argument "flags"
is a string that may be empty (the default) or contain
one or more of regex flag characters.

*** filter re_sub(pattern, repl[, flags[, count]])
Return the string obtained by replacing the leftmost non-overlapping
occurrences of pattern in string by the replacement repl.
If the pattern isn't found, string is returned unchanged.

repl must be a string. Any backslash escapes in it are processed.
That is, \n is converted to a single newline character, \r is
converted
to a linefeed, and so forth. Unknown escapes such as \j are left
alone.
Backreferences, such as \6, are replaced with the substring
matched by group 6 in the pattern.

The optional argument "flags" is similar to the flags argument
in test re_match() (see above).

The optional argument count is the maximum number of pattern
occurrences to be replaced; count must be a non-negative integer.
If omitted or zero, all occurrences will be replaced.

*** filter re_escape

Return string with all non-alphanumerics backslashed;
this is useful if you want to match an arbitrary literal
string that may have regular expression metacharacters in it.

---

The regex flag characters are explained below.
Unknown flag chars are silently ignored.

(see also: http://docs.python.org/library/re.html)

"i" (re.I, re.IGNORECASE)
"l" (re.L, re.LOCALE)
"m" (re.M, re.MULTILINE)
"s" (re.S, re.DOTALL)
"u" (re.U, re.UNICODE)
"x" (re.X, re.VERBOSE)

---

The "re" extensions are this simple to add to Jinja2:

---
import re

def get_re_flags(flagstr):
    reflags = 0
    if flagstr:
        if flagstr.find("i") > -1: reflags |= re.IGNORECASE
        if flagstr.find("l") > -1: reflags |= re.LOCALE
        if flagstr.find("m") > -1: reflags |= re.MULTILINE
        if flagstr.find("s") > -1: reflags |= re.DOTALL
        if flagstr.find("u") > -1: reflags |= re.UNICODE
        if flagstr.find("x") > -1: reflags |= re.VERBOSE
    return reflags

def is_re_match(s, rs, flagstr=None):
    reflags = get_re_flags(flagstr)
    if re.search(rs, s, reflags):
        return True
    else:
        return False

def filter_re_sub(s, rs, repl, flagstr=None, count=0):
    reflags = get_re_flags(flagstr)
    myre = re.compile(rs, reflags)
    return re.sub(myre, repl, s, count)

def filter_re_escape(s):
    return re.escape(s)

...
    ld_dot = jinja2.FileSystemLoader(root)
    ld_sys = jinja2.FileSystemLoader(TMPLDIR)
    ch_loader = jinja2.ChoiceLoader((ld_dot, ld_sys))
    jenv = jinja2.Environment(loader=ch_loader, trim_blocks=True)
    jenv.tests['re_match'] = is_re_match
    jenv.filters['re_sub'] = filter_re_sub
    jenv.filters['re_escape'] = filter_re_escape
    tmpl = jenv.get_template(templatefile)

---

I have tested those beasts in some test templates involving
the use of CFengine 3 class definitions, that include lots of
different data about server configuration and state. Those data
is put into the list "cf" and used like this in the template:

{% set svc_list = [] %}
{% set if_list = [] %}
{% set ip_list = [] %}

{% for c in cf %}
{% if c is re_match("^service_", "i") %}
{% set svcname = c | re_sub("^service_", "", "i", 1) %}
{% set svc_list = svc_list + [svcname] %}
{% endif %}
{% if c is re_match("^net_iface_") %}
{% set ifname = c | re_sub("^net_iface_", "") %}
{% set if_list = if_list + [ifname] %}
{% endif %}
{% if c is re_match("^ipv4_") %}
{% set ipname = c | re_sub("^ipv4_(.*)", "ip4-\\1") | re_sub("_", ".")
%}
{% set ip_list = ip_list + [ipname] %}
{% endif %}
{% endfor %}

Enabled services:
{% for s in svc_list %}
SVC({{loop.index0}})={{s}}
{% endfor %}

Interfaces:
{% for s in if_list %}
IF({{loop.index0}})={{s}}
{% endfor %}

IP addresses:
{% for s in ip_list %}
IP({{loop.index0}})={{s}}
{% endfor %}

-- 
You received this message because you are subscribed to the Google Groups 
"pocoo-libs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pocoo-libs?hl=en.

Reply via email to