Mailing List Archive

Alternative dictionary output format?
I would like to be able to take a string which contains C-format
extension variables (e.g., "%(foo)s") and format it with a dictionary in
the standard way, except I would like the format to only substitute for
the recognized variables and to ignore other instances of percent signs.

For example, given this program:

s = "%(href)s/foo/bar?x=%m&y=%n"
d = {'href': "http://www.gomer.com"}
u = s % d
print s

running it produces:

% python t.py
Traceback (innermost last):
File "t.py", line 3, in ?
u = s % d
TypeError: not enough arguments for format string

And this program:

s = "%m foobar %(href)s/foo/bar?x=%m&y=%n"
d = {'href': "http://www.gomer.com"}
u = s % d
print s

produces:

% python t.py
Traceback (innermost last):
File "t.py", line 3, in ?
u = s % d
ValueError: unsupported format character 'm' (0x6d)

What I would like to write:

s = "%m foobar %(href)s/foo/bar?x=%m&y=%n"
d = {'href': "http://www.gomer.com"}
u = format_ignoring_non_variable_percent_signs(s, d)
print s

And what I would like the behavior to be:

% python t.py
%m foobar http://www.gomer.com/foo/bar?x=%m&y=%n

Is there any way to surface the C interface for the '%' format operator
and to allow an option to effectively wrap each format attempt with a
try/except/pass block?

I realize there are other ways to do this (regular expression
substitution, write my own C extension, etc.), but formatting a string
with multiple variables using a dictionary and the format operator is
extremely convenient (and I imagine relatively effiecient), and I
thought others may have come across this as well.


Bill
--
r a e l @
d e j a .
c o m


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
Alternative dictionary output format? [ In reply to ]
On Fri, 04 Jun 1999 14:55:42 GMT, rael@my-deja.com
<rael@my-deja.com> wrote:
>s = "%(href)s/foo/bar?x=%m&y=%n"

(he wants to only substitute the %(href) and not the rest)

s = "%(href)s/foo/bar?x=%%m&y=%%n"

i.e., double the percents you want to have not interpolated at this stage
of the game.

A clever regular expression might be able to do this for you, but the way
to write it 100% bulletproof escapes me.

Jeff
--
\/ http://www.slashdot.org/ Jeff Epler jepler@inetnebr.com
I just forgot my whole philosophy of life!!!
Alternative dictionary output format? [ In reply to ]
I don't know if this is 100% bulletproof, but it has simple behavior:

pctsub = re.compile('%(?!%*\()').sub
def pfstr(s, pctsub = pctsub):
'''Double all '%' except those leading up to a '(', for dict formatting'''
return pctsub('%%', s)

>>> pfstr("%(href)s/foo/bar?x=%m&y=%n") % {'href': 'baz' }
'baz/foo/bar?x=%m&y=%n'

All percent signs pass unharmed, except for those in front of a left paren.
In that case '%(href)' => 'baz', '%%(href)' => '%(href)', '%%%(href)' =>
'%baz', etc.

Jeff Epler wrote in message ...
On Fri, 04 Jun 1999 14:55:42 GMT, rael@my-deja.com
<rael@my-deja.com> wrote:
>s = "%(href)s/foo/bar?x=%m&y=%n"

(he wants to only substitute the %(href) and not the rest)

s = "%(href)s/foo/bar?x=%%m&y=%%n"

i.e., double the percents you want to have not interpolated at this stage
of the game.

A clever regular expression might be able to do this for you, but the way
to write it 100% bulletproof escapes me.
Alternative dictionary output format? [ In reply to ]
Evan Simpson writes:
>I don't know if this is 100% bulletproof, but it has simple behavior:
>pctsub = re.compile('%(?!%*\()').sub
>def pfstr(s, pctsub = pctsub):
> '''Double all '%' except those leading up to a '(', for dict formatting'''
> return pctsub('%%', s)

An alternative is re.sub('%([^(]|\Z)', r'%%\1', <string>) . The [^(]
| \Z will match either any character that's not a (, or at the end of
the string. The \Z is needed in order to handle a trailing '%' --
regexes are tricky.

--
A.M. Kuchling http://starship.python.net/crew/amk/
You mustn't kill me. You don't love me. You d-don't even know me.
-- The Furies kill Abel, in SANDMAN #66: "The Kindly Ones:10"