2016-02-10 39 views
0

我環顧四周尋找一個定製的解決方案,但我無法找到我面臨的用例的解決方案。自定義的非ASCII字符標記

使用案例

我建立一個「網站」 QA測試,其中腳本會通過批量HTML文件,並找出任何惡意字符。我不能使用純非ASCII方法,因爲HTML文檔包含諸如「>」和其他次要字符的字符。因此,我正在製作一本unicode彩虹字典,用於標識我的團隊和我經常看到的一些非ASCII字符。以下是我的Python代碼。

# -*- coding: utf-8 -*- 

import re 

unicode_rainbow_dictionary = { 
    u'\u00A0':' ', 
    u'\uFB01':'fi', 
} 

strings = ["This contains the annoying non-breaking space","This is fine!","This is not fine!"] 

for string in strings: 
    for regex in unicode_rainbow_dictionary: 
     result = re.search(regex,string) 
     if result: 
      print "Epic fail! There is a rogue character in '"+string+"'" 
     else: 
      print string 

這裏的問題是字符串數組中的最後一個字符串包含非ascii連字符(合併的fi)。當我運行這個腳本時,它不捕獲連字符,但它捕獲第一種情況下的不可破壞的空格字符。

什麼是導致誤報?

+0

爲什麼不'從字符串進口ascii_characters'使用,並說'如果不信的ascii_characters'? – ATLUS

+0

@ATLUS我不能使用純粹的非ascii方法,因爲HTML文檔包含諸如「>」和其他次要字符的字符。例如,「Learn More>」 – Adib

+0

爲什麼不實現一個你不想包含的字符串,比如'>'?如果你打印'ascii_letters',你可以從字面上得到'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',那麼爲什麼不加上你自己的字符串,如'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ <>'/'etc – ATLUS

回答

2

使用Unicode字符串作爲@jgfoot指出的所有文本。最簡單的方法是使用from __future__將字符串默認爲Unicode文字。此外,使用print作爲一個功能將使2/3兼容的代碼的Python:

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals,print_function 
import re 

unicode_rainbow_dictionary = { 
    '\u00A0':' ', 
    '\uFB01':'fi', 
} 

strings = ["This contains the\xa0annoying non-breaking space","This is fine!","This is not fine!"] 

for string in strings: 
    for regex in unicode_rainbow_dictionary: 
     result = re.search(regex,string) 
     if result: 
      print("Epic fail! There is a rogue character in '"+string+"'") 
     else: 
      print(string) 
0

您的代碼無法按預期工作,因爲在您的「strings」變量中,您在非unicode字符串中具有unicode字符。你忘記把「u」放在他們面前,表示他們應該被當作unicode字符串。

strings = [u"This contains the annoying non-breaking space",u"This is fine!",u"This is not fine!"] 

它按預期工作:所以,當你搜索一個非Unicode字符串中Unicode字符串,它並沒有如預期

如果你改變了這個工作。

解決unicode的頭痛這個樣子的Python 3

的主要好處這裏是一種替代方法,您的問題。怎麼樣只是試圖將字符串編碼爲ASCII,並捕捉錯誤,如果它不能正常工作?:

def is_this_ascii(s): 
    try: 
     ignore = unicode(s).encode("ascii") 
     return True 
    except (UnicodeEncodeError, UnicodeDecodeError): 
     return False 

strings = [u"This contains the annoying non-breaking space",u"This is fine!",u"This is not fine!"] 

for s in strings: 
    print(repr(is_this_ascii(s))) 

##False 
##True 
##False 
1

如果有,則可能儘快切換到Python 3越好! Python 2不擅長處理unicode,而Python 3本身就是這樣做的。

for string in strings: 
    for character in unicode_rainbow_dictionary: 
     if character in string: 
      print("Rogue character '" + character + "' in '" + string + "'") 

我無法在我的測試中獲得不間斷的空間。我通過使用"This contains the annoying" + chr(160) + "non-breaking space"來解決這個問題。

+0

我會看看我是否可以轉向Python 3,但由於遺留原因,我們一直在使用Python 2 ... yay legacy -.-但是你提供的解決方案看起來非常簡單 – Adib