Chinaunix首页 | 论坛 | 博客
  • 博客访问: 915366
  • 博文数量: 75
  • 博客积分: 1216
  • 博客等级: 少尉
  • 技术积分: 1998
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-11 16:20
个人简介

优秀是一种习惯

文章分类

全部博文(75)

文章存档

2014年(1)

2013年(29)

2012年(45)

分类: Python/Ruby

2012-12-30 13:21:02

string.Template类是一个字符串模板,用来搜索字符串中的$var ${var},然后使用类中的substitute()方法替换字符串中的变量。
${var}用在变量var后有可以组成变量名的字符串。
如果相输出$则,使用 $$

  1. >>> values={'stu1':'tom','stu2':'selina','stu3':'harry'}
  2. >>> t=string.Template("i'm $stu1\n;$stu2 have $$100")
  3. >>> t.substitute(values)
  4. "i'm tom\n;selina have $100"
其中默认的变量名字的格式是:idpattern = r'[_a-z][_a-z0-9]*'
分隔符是:delimiter = '$'
如果想修改变量名和分隔符的格式,可以修改这两个变量

  1. [root@station1 ~]# vim mytemplate.py
  2. #!/usr/bin/python
  3. import string
  4. class Mytemplate(string.Template):
  5.         delimiter = "%"
  6.         idpattern = "_[a-z]+"

  7. s = '''delimiter is %%
  8.         replaced : %_stu
  9.         no replaced : %stu
  10. '''
  11. values = {"_stu":"tom","stu":"selina"}
  12. t=Mytemplate(s)
  13. print '%s' % t.safe_substitute(values)
执行结果

  1. [root@station1 ~]# python mytemplate.py
  2. delimiter is %
  3. replaced : tom
  4. no replaced : %stu


下面是此类的源代码:

  1. import re as _re

  2. class _multimap:
  3.     """Helper class for combining multiple mappings.

  4.     Used by .{safe_,}substitute() to combine the mapping and keyword
  5.     arguments.
  6.     """
  7.     def __init__(self, primary, secondary):
  8.         self._primary = primary
  9.         self._secondary = secondary

  10.     def __getitem__(self, key):
  11.         try:
  12.             return self._primary[key]
  13.         except KeyError:
  14.             return self._secondary[key]

  15. class _TemplateMetaclass(type):
  16.     pattern = r"""
  17.     %(delim)s(?:
  18.       (?P%(delim)s) | # Escape sequence of two delimiters
  19.       (?P%(id)s) | # delimiter and a Python identifier
  20.       {(?P%(id)s)} | # delimiter and a braced identifier
  21.       (?P) # Other ill-formed delimiter exprs
  22.     )
  23.     """

  24.     def __init__(cls, name, bases, dct):
  25.         super(_TemplateMetaclass, cls).__init__(name, bases, dct)
  26.         if 'pattern' in dct:
  27.             pattern = cls.pattern
  28.         else:
  29.             pattern = _TemplateMetaclass.pattern % {
  30.                 'delim' : _re.escape(cls.delimiter),
  31.                 'id' : cls.idpattern,
  32.                 }
  33.         cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE)


  34. class Template:
  35.     """A string class for supporting $-substitutions."""
  36.     __metaclass__ = _TemplateMetaclass

  37.     delimiter = '$'
  38.     idpattern = r'[_a-z][_a-z0-9]*'

  39.     def __init__(self, template):
  40.         self.template = template

  41.     # Search for $$, $identifier, ${identifier}, and any bare $'s

  42.     def _invalid(self, mo):
  43.         i = mo.start('invalid')
  44.         lines = self.template[:i].splitlines(True)
  45.         if not lines:
  46.             colno = 1
  47.             lineno = 1
  48.         else:
  49.             colno = i - len(''.join(lines[:-1]))
  50.             lineno = len(lines)
  51.         raise ValueError('Invalid placeholder in string: line %d, col %d' %
  52.                          (lineno, colno))

  53.     def substitute(self, *args, **kws):
  54.         if len(args) > 1:
  55.             raise TypeError('Too many positional arguments')
  56.         if not args:
  57.             mapping = kws
  58.         elif kws:
  59.             mapping = _multimap(kws, args[0])
  60.         else:
  61.             mapping = args[0]
  62.         # Helper function for .sub()
  63.         def convert(mo):
  64.             # Check the most common path first.
  65.             named = mo.group('named') or mo.group('braced')
  66.             if named is not None:
  67.                 val = mapping[named]
  68.                 # We use this idiom instead of str() because the latter will
  69.                 # fail if val is a Unicode containing non-ASCII characters.
  70.                 return '%s' % (val,)
  71.             if mo.group('escaped') is not None:
  72.                 return self.delimiter
  73.             if mo.group('invalid') is not None:
  74.                 self._invalid(mo)
  75.             raise ValueError('Unrecognized named group in pattern',
  76.                              self.pattern)
  77.         return self.pattern.sub(convert, self.template)

  78.     def safe_substitute(self, *args, **kws):
  79.         if len(args) > 1:
  80.             raise TypeError('Too many positional arguments')
  81.         if not args:
  82.             mapping = kws
  83.         elif kws:
  84.             mapping = _multimap(kws, args[0])
  85.         else:
  86.             mapping = args[0]
  87.         # Helper function for .sub()
  88.         def convert(mo):
  89.             named = mo.group('named')
  90.             if named is not None:
  91.                 try:
  92.                     # We use this idiom instead of str() because the latter
  93.                     # will fail if val is a Unicode containing non-ASCII
  94.                     return '%s' % (mapping[named],)
  95.                 except KeyError:
  96.                     return self.delimiter + named
  97.             braced = mo.group('braced')
  98.             if braced is not None:
  99.                 try:
  100.                     return '%s' % (mapping[braced],)
  101.                 except KeyError:
  102.                     return self.delimiter + '{' + braced + '}'
  103.             if mo.group('escaped') is not None:
  104.                 return self.delimiter
  105.             if mo.group('invalid') is not None:
  106.                 return self.delimiter
  107.             raise ValueError('Unrecognized named group in pattern

阅读(1830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~