2015-11-11

python regular expression 參數小技巧


測試小結果
1.  python regular expression 的參數中 re.Locale 跟 re.Unicode 有很大的不同,unicode 會讓 英文字跟中文字視為文字: \w ; 而 locale 會讓地區字,如中文,跟英文視為不同字, 此時的 \w 只單指英文字
   
re.L (locale)會讓 regular 在遇到中文時才會判斷 \b(即\w\W交換邊界)
re.U (unicode)會讓 regular 在遇到空白' '時才會判斷 \b(即\w\W交換邊界), 中英字都算 \w

請看例子
>>> re.findall(r'\b\d+\.?\d*\ {0,2}[份吋寸度瓶]{1,2}\b', " 2 瓶  w", re.U)
['2 瓶']
發現了嗎?空白' ' 跟中文字被視為邊界
>>> re.findall(r'\b\d+\.?\d*\ {0,2}[份吋寸度瓶]{1,2}\b', " 2 瓶  w", re.L)
[]
發現了嗎?空白' ' 跟中文字非邊界字

>>> re.findall(r'\b\d+\.?\d*\ {0,2}[份吋寸度瓶]{1,2}\b', "2 瓶w", re.U)
[]
在unicode 時英文=中文
>>> re.findall(r'\b\d+\.?\d*\ {0,2}[份吋寸度瓶]{1,2}\b', "2 瓶w", re.L)
['2 瓶']
在locale 時英文 跟 中文 又變成不同國了

掌握這種小技巧,你就可以無往不利了
要寫出一個超強的 re 解析器也就不是什麼難事了

def get_product_regex():
    regex = []
    special_words = ['.*(?:多拉|哆啦)[Aa]夢',
                     '漢堡QQ糖', "M&M's", "\d{2}姨"
                    ]
   
    special_words = "|".join(special_words)
    regex += [special_words]
    # << 先用中文分開所有字串 >>
    #regex += [r'\b[a-zA-Z]{1,2}\ *號[^\w\b']
    regex += [r'[\d\.]+[合][\d\.]+']
    regex += [r'[\d\.]+[倍元入種切枚包組箱粒支號盒公分升斤束片張重瓦尺年份吋寸度瓶]{1,2}']
    regex += [r'[LMXSlmxs]{1,2}\ *[號]{1,2}']
    regex += [r'[\u4e00-\ufaff /]+']
    # 數字+單位
    regex += [r'\d+\.?\d*(?:[mM][lL]|[kK][gG]|[cC][mM]|[oO][zZ]|gm|g|[cC][cC]|%)']
   
    #regex += ['[a-zA-Z\d\'\"\.\*\-&~]+']
   
    # << 英文部分處理 >>
    # 數字加一個 " 或 ' 結束 (avex note: 使用 re.Local 時 ' " 無法配合\b判斷, 故要獨立)
    regex += [r'\d+\.?\d*[\"\'%/]']
    # ex, 123 x 456
    regex += [r'\d+\ *[\*xX]\ *\d+']
    # 數字加一個以英文字母結束;
    regex += [r'\d+\.?\d+\b']
    regex += [r'\d+\.?\d*[A-Za-z]\b']
    regex += [r'\d+\.?\d*[A-Za-z]+']
   
    # 英文
    regex += [r'[a-zA-Z]+\.[a-zA-Z]+\b']
#    regex += [r'\b[a-zA-Z,\.\~]+\b']
#     regex += [r'\b[a-zA-Z]+\b']
    # 大寫英文
    #regex += [r'(?<=[\d\.])[A-Z]+\b|[A-Z]+\b']
   
    # 數字
    regex += [r'\d+\"?\'?']
   
    # 英文含數字
    regex += [r'[a-zA-Z\d\-\+\'\ \"\.~/]+']

    s_reg = "|".join(regex)
    #print(s_reg)
    #r = re.compile(s_reg, re.IGNORECASE)
    r = re.compile(s_reg, re.L)
   
    return r


測試字串:
>>>s = '0.5L佳珍密封罐 000060 4DC 12V車用電風扇5" 插式sp1627df uE-35、L號 R.F 12升貝納頌100%拿鐵3合1裝2.3kg咖啡2oz(22g*10)6入'

>>> r.findall(s)

['0.5L', '佳珍密封罐 ', '000060', ' ', '4DC', ' ', '12V', '車用電風扇', '5"', ' 插式', 'sp1627df uE-35', 'L號', ' ', 'R.F', ' ', '12升', '貝納頌', '100%', '拿鐵', '3合1', '裝', '2.3kg', '咖啡', '2oz', '22g', '10', '6入']



看吧,這麼複雜的字串都可以幫你分類的好好的,大數據就是要從基礎建設開始



python 支援的正規表示式(regular expression) function 比較

match: 依規則搜尋單一結果,搜尋一定是從頭(^)開始比對,即使用 re.MULTILINE
search: 依規則搜尋單一結果,搜尋不需要是從頭(^)開始比對,若要限制一定從頭比對可以加入 ^,例如 "^要找的規則"
findall: 用 search 去搜尋,並且給出多個結果

finditer: 同 findall, 但回傳資料同 match 有position資料,而非 findall 的 string




沒有留言:

張貼留言