Created
November 14, 2017 23:01
-
-
Save pekeq/9c0fc099f4203a4299289db29507cad7 to your computer and use it in GitHub Desktop.
オレオレ正規化処理 (Python3)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf8 | |
# オレオレ正規化処理 (Python3) | |
# 正規表現コンパイルをメソッドの外に書いたのでそこそこ速い | |
import re | |
import unicodedata | |
# inspired from https://github.com/neologd/mecab-ipadic-neologd/wiki/Regexp.ja | |
# 以下を参考させていただきました | |
# http://d.hatena.ne.jp/s_hiiragi/20110111/1294755929 | |
# https://hydrocul.github.io/wiki/blog/2014/1101-hyphen-minus-wave-tilde.html | |
# https://github.com/ikegami-yukino/neologdn | |
# https://ja.wikipedia.org/wiki/%E3%83%8F%E3%82%A4%E3%83%95%E3%83%B3 | |
# https://ja.wikipedia.org/wiki/%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5 | |
# 幅のない空白 | |
# - 右から書く言語で使うU+200E, U+200FはSPACEではないが、ここに入れる | |
# - soft hyphen U+00AD もここに入れる | |
re_ZERO_WIDTH_SPACES = re.compile(r'[\u200B\u200C\u200D\u200E\u200F\uFEFF\u00AD]') | |
# 各種空白文字 | |
re_SPACES = re.compile(r'[ \t\u2028\u2029\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000]+') | |
# ハイフンに統一するもの | |
re_HYPHENS = re.compile(r'[\u2010\u002D\u2011\u2043\u2212]+') | |
# wavedashに統一するもの | |
re_WAVEDASHES = re.compile(r'[\u301C\u02DC\u1FC0\u2053\u223C\u223F\u3030\uFF5E]+') | |
# 長音 | |
re_CHOONPUS = re.compile(r'\u30FC+') | |
# 実体参照 | |
re_AMP = re.compile(r'&') | |
re_QUOT = re.compile(r'"') | |
re_LT = re.compile(r'<') | |
re_GT = re.compile(r'>') | |
# 全角ダブルクォートを半角に | |
REPLACE_QUOTES = str.maketrans('”“’‘', '""\'\'') | |
# 軽い(?)正規化処理 | |
# 表記のゆれを整える程度 | |
def normalize(s): | |
# 幅のない空白は削除 | |
s = re_ZERO_WIDTH_SPACES.sub('', s) | |
# 一部の実体参照を展開 | |
s = re_AMP.sub('&', s) | |
s = re_QUOT.sub("'", s) | |
s = re_LT.sub('<', s) | |
s = re_GT.sub('>', s) | |
# 全角ダブルクォートを半角に | |
s = s.translate(REPLACE_QUOTES) | |
# unicode正規化 | |
s = unicodedata.normalize('NFKC', s) | |
# ハイフンゆれ | |
s = re_HYPHENS.sub('-', s) | |
# wavedashゆれ | |
s = re_WAVEDASHES.sub('\u301C', s) | |
# 長音まとめる | |
s = re_CHOONPUS.sub('\u30FC', s) | |
# 空白文字まとめる | |
s = re_SPACES.sub(' ', s) | |
return s.strip() | |
# カット対象 | |
# - 変換されなかった実体参照 | |
re_TO_STRIP = re.compile(r'&[#\w\d]+;') | |
# カット対象(空白に変換) | |
# - wikipediaの図表,code引用 | |
re_TO_SPACE = re.compile(r'(formula|codice)_\d+') | |
# 数字 | |
re_NUMBERS = re.compile(r'\d+') | |
# ローマ数字は全部 0 に変換 | |
REPLACE_ROMANS = str.maketrans('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ', '0000000000') | |
# word2vecする前の正規化処理 | |
def full_normalize(s): | |
# ローマ数字 | |
s = s.translate(REPLACE_ROMANS) | |
# スペースに変換 | |
s = re_TO_SPACE.sub(' ', s) | |
s = normalize(s) | |
# 不要部分削除 | |
s = re_TO_STRIP.sub('', s) | |
# 英文字は小文字に | |
s = s.lower() | |
# 数字は0に変換。連続していたらまとめる | |
s = re_NUMBERS.sub('0', s) | |
return s | |
if __name__ == "__main__": | |
assert '' == normalize('\u200B\u200C\u200D\u200E\u200F\uFEFF') | |
assert 'ルパンIII世' == normalize('ルパンⅢ世') | |
assert 'ルパン0世' == full_normalize('ルパンⅢ世') | |
assert 'copy&right' == full_normalize('copy&right©') | |
assert 'g0カービン' == full_normalize('G13カービン') | |
assert '空 白 空 白' == normalize('空 白 空 白') | |
assert "お\"お\"" == normalize("お“お”") | |
assert "ハンカク" == normalize("ハンカク") | |
assert "0" == full_normalize("0123456789") | |
assert "abcdefghijklmnopqrstuvwxyz" == full_normalize("ABCDEFGHIJKLMNOPQRSTUVWXYZ") | |
assert "abcdefghijklmnopqrstuvwxyz" == normalize("abcdefghijklmnopqrstuvwxyz") | |
assert "!\"#$%&'()*+,-./:;<>?@[¥]^_`{|}" == normalize("!”#$%&’()*+,-./:;<>?@[¥]^_`{|}") | |
assert "=。、・「」" == normalize("=。、・「」") | |
assert "ハンカク" == normalize("ハンカク") | |
assert "o-o" == normalize("o₋o") | |
#assert "majikaー" == normalize("majika━") | |
assert "わ〜い" == normalize("わ〰い") | |
assert "スーパー" == normalize("スーパーーーー") | |
assert "!#" == normalize("!#") | |
assert "ゼンカク スペース" == normalize("ゼンカク スペース") | |
assert "お お" == normalize("お お") | |
assert "おお" == normalize(" おお") | |
assert "おお" == normalize("おお ") | |
assert "-" == normalize('---------------') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment