2013-03-26 39 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