Implementing "title formatting" in Python
I'm writing a "title formatting" parser in Python, a la foobar2000 and Winamp. It basically works like this:
"%artist% - %title%" -> "The Beatles - Yellow Submarine"
"%title% by $upper(%artist%)" -> "Yellow Submarine by THE BEATLES"
That's a simple example; look here or here for reference.
Can anyone point me in the right direction? I've tried -- and failed -- with regex and lex/yacc.
EDIT: Along with
%variables%
and$functions()
, I also have to implement single quotation marks (which surround raw text) and square parentheses (see the ref开发者_如何学Pythonerences!).
Does it have to be in that exact format? Python's own string formatting is nice:
>>> tags = {'title': 'Yellow Submarine', 'artist': 'The Beatles'}
>>> tags['upperartist'] = tags['artist'].upper()
>>> '{title} by {upperartist}'.format(**tags)
'Yellow Submarine by THE BEATLES'
For anything much more complicated, I'd pick one of the many Python templating engines. Templates are fun to write - that's why there are so darn many of them! - but I bet one of them would already do just when you want.
Well multiple regex calls are an option.
To recognize a variable you should use %\w*%
and to recognize a function call \$\w*\(\w*\)
You then incrementally search for variables and substitute them for their value and for function calls and substitute them by passing the data inside the parethesis to an actual function and pasting the result. Is that what you tried?
Here's sample I wrote that might help. You will need to expand subs
, functions
and apply_func
as per your needs.
#!/usr/bin/python
import re
# Variables to be substituted
subs = ["title", "artist"]
# Functions to be applied
functions = ["upper", "lower"]
# How to apply a function to the argument
def apply_func(f, arg):
if f == "upper":
return arg.upper()
if f == "lower":
return arg.lower()
def get_title(title, values):
# Substitute the variables first
for s in subs:
title = title.replace("%"+s+"%", values[s])
# Apply the functions
for f in functions:
fre = re.compile("\$("+f+")\((.*)\)")
result = fre.search(title)
if result:
arg = result.group(2)
title = title.replace("$"+f+"("+arg+")", apply_func(f, arg))
return title
def main():
#title = "%title% by $upper(%artist%)"
title = "$lower(%artist%) -> $upper(%title%)"
values = {'title' : "Yellow Submarine", 'artist' : "The Beatles"}
print get_title(title, values)
if __name__ == '__main__':
main()
精彩评论