[Python-ideas] idea: Template.match function
Joe Strout
joe at strout.net
Sat Oct 11 00:50:07 CEST 2008
OK, here's my pitch -- in rough PEP form, even though this may be
small enough to not merit a PEP. I'd really like your feedback on
this idea.
Abstract
I propose we add a new function on the string.Template [1] class,
match(), to perform the approximate inverse of the existing
substitute() function. That is, it attempts to match an input string
against a template, and if successful, returns a dictionary providing
the matched text for each template field.
Rationale
PEP 292 [2] added a simplified string substitution feature, allowing
users to easily substitute text for named fields in a template
string. The inverse operation is also useful: given a template and an
input string, one wishes to find the text in the input string matching
the fields in the template. However, Python currently has no easy way
to do it.
While this named matching operation can be accomplished using RegEx,
the constructions required are somewhat complex and error prone. It
can also be done using third-party modules such as pyparse, but again
the setup requires more code and is not obvious to programmers
inexperienced with that module.
In addition, the Template class already has all the data needed to
perform this operation, so it is a natural fit to simply add a new
method on this class to perform a match, in addition to the existing
method to perform a substitution.
Proposal
Proposed is the addition of one new attribute, and one new function,
on the existing Template class, as follows:
1. 'greedy' is a new attribute that determines whether the field
matches should be done in a greedy manner, equivalent to regex pattern
'(.*)'; or in a non-greedy manner, equivalent to '(.*?)'. This
attribute defaults to false.
2. 'match' is a new function which accepts one parameter, an input
string. If the input string can be matched to the template pattern
(respecting the 'greedy' flag), then match returns a dictionary, where
each field in the pattern maps to the corresponding part of the input
string. If the input string cannot be matched to the template
pattern, then match returns NOne.
Examples:
>>> from string import Template
>>> s = Template('$name was born in ${country}')
>>> print s.match('Guido was born in the Netherlands')
{'name':'Guido', 'country':'the Netherlands'}
>>> print s.match('Spam was born as a canned ham')
None
Note that when the match is successful, the resulting dictionary could
be passed through Template.substitute to reconstitute the original
input string. Conversely, any string created by Template.substitute
could be matched by Template.match (though in unusual cases, the
resulting dictionary might not exactly match the original, e.g. if the
string could be matched in multiple ways). Thus, .match
and .substitute are inverse operations.
References
[1] Template Strings
http://www.python.org/doc/2.5.2/lib/node40.html
[2] PEP 292: Simpler String Substitutions
http://www.python.org/dev/peps/pep-0292/
More information about the Python-ideas
mailing list