2009-11-17 151 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的東西。