2013-03-26 46 views
4

我有一些代码,我认为应该返回不在字符串中的python语句的所有部分。但是,我不确定这是否符合我的要求。基本上,它只是找到下一个字符串分隔符,并保持在“字符串”状态,直到它被相同的分隔符关闭。我有没有想过的一些奇怪的情况,我做了什么不对?它会以什么方式与python不一致?这段代码是否正确识别python字符串

# String delimiters in order of precedence 
string_delims = ["'''",'"""',"'",'"'] 

# Get non string parts of a statement 
def get_non_string(text): 

    out = "" 
    state = None 

    while True: 

     # not in string 
     if state == None: 
      vals = [text.find(s) for s in string_delims] 

      # None will only be reached if all are -1 (i.e. no substring) 
      for val,delim in zip(vals+[None], string_delims+[None]): 
       if val == None: 
        out += text 
        return out 

       if val >= 0: 
        i = val 
        state = delim 
        break 

      out += text[:i] 
      text = text[i+len(delim):] 

     else: 
      i = text.find(state) 
      if i < 0: 
       raise SyntaxError("Symobolic Subsystem: EOL while scanning string literal") 
      text = text[i+len(delim)] 
      state = None 

示例输入:

get_non_string("hello'''everyone'''!' :)'''") 

示例输出:

hello! 

回答

3

Python可以标记化Python代码:

import tokenize 
import token 
import io 
import collections 

class Token(collections.namedtuple('Token', 'num val start end line')): 
    @property 
    def name(self): 
     return token.tok_name[self.num] 

def get_non_string(text): 
    result = [] 
    for tok in tokenize.generate_tokens(io.BytesIO(text).readline): 
     tok = Token(*tok) 
     # print(tok.name, tok.val) 
     if tok.name != 'STRING': 
      result.append(tok.val) 
    return ''.join(result)  

print(get_non_string("hello'''everyone'''!' :)'''")) 

产量

hello! 

这个繁重的工作是由tokenize.generate_tokens完成的。

+0

酷,这就是我正在寻找的答案:) – Lucas 2013-03-26 19:52:21

+0

请注意,\ n字符串中的字符可能会导致意外的结果,如在这种情况下:'print(get_non_string(“*'\ n'”) )''不会去掉'\ n'' – furins 2013-03-26 19:55:11

1

您自己的代码在多个案例中存在问题,因为您似乎没有对转义报价做出任何规定("\"","""\""""等)。

另外:

get_on_string('""') 

引发错误。

我不会把它描述为奇怪的情况。

+0

是的,完全忘了逃生字符。我会把''“'''描述为一个奇怪的例子,尽管不是它不应该处理的:) – Lucas 2013-03-26 20:07:22