2009-11-17 114 views

回答

9

有趣的是有一个无证Scannerre模块:

import re 

def s_ident(scanner, token): return token 
def s_operator(scanner, token): return "op%s" % token 
def s_float(scanner, token): return float(token) 
def s_int(scanner, token): return int(token) 

scanner = re.Scanner([ 
    (r"[a-zA-Z_]\w*", s_ident), 
    (r"\d+\.\d*", s_float), 
    (r"\d+", s_int), 
    (r"=|\+|-|\*|/", s_operator), 
    (r"\s+", None), 
    ]) 

print scanner.scan("sum = 3*foo + 312.50 + bar") 

继它看起来就像是在为实验代码/起点为别人留下的discussion

+0

有趣,谢谢! – 2009-11-17 21:54:23

4

在Python中没有什么和Ruby的StringScanner一模一样。当然,容易把东西在一起:

import re 

class Scanner(object): 
    def __init__(self, s): 
     self.s = s 
     self.offset = 0 
    def eos(self): 
     return self.offset == len(self.s) 
    def scan(self, pattern, flags=0): 
     if isinstance(pattern, basestring): 
      pattern = re.compile(pattern, flags) 
     match = pattern.match(self.s, self.offset) 
     if match is not None: 
      self.offset = match.end() 
      return match.group(0) 
     return None 

随着交互使用它的一个例子

>>> s = Scanner("Hello there!") 
>>> s.scan(r"\w+") 
'Hello' 
>>> s.scan(r"\s+") 
' ' 
>>> s.scan(r"\w+") 
'there' 
>>> s.eos() 
False 
>>> s.scan(r".*") 
'!' 
>>> s.eos() 
True 
>>> 

但是,我做我往往只写一次过那些正则表达式的工作并使用组提取所需的字段。或者对于更复杂的事情,我会写一个一次性的标记器,或者寻找PyParsing或PLY来为我标记。我没有看到自己使用类似StringScanner的东西。