def drain(idx_rows, data_rows): idx = [] idx_idx = [] slot = [] for ci,c in enumerate(list(zip(*idx_rows))): if not "".join(c): continue for i,v in enumerate(c): v = jaconv.normalize(v).replace(" ","") if v: slot = slot[:i]+[v] idx.append(" ".join(slot)) idx_idx.append(ci) data = [] for d in data_rows: if not "".join([d[i] for i in idx_idx]): continue dr = [] for i in idx_idx: dr.append(override.get(idx[len(dr)], d[i])) data.append(dr) return idx, data
def eval_force_romaji_to_kana_v2(self, text, kana_ref, nbest=20): p_ = jaconv.z2h(text, digit=True, ascii=True, kana=False) # hankaku p_ = jaconv.normalize(p_, "NFKC") p = jaconv.alphabet2kata(p_) # romanize as possible if p_ == p: return 12345 return self.eval_normal(p, kana_ref, nbest)
def search_members(q_info): _text = q_info['text'] # 全角 ⇒ 半角 & ノーマライズ. ex) 'kAげヤmay' => 'kAげヤmay' cleaned_text = jaconv.normalize(_text, 'NFKC') # カタカナ => ひらがな. ex) 'kAげヤmay' => 'kAげやmay' cleaned_text = jaconv.kata2hira(cleaned_text) # 大文字 => 小文字. ex) 'kAげやmay' => 'kaげやmay' cleaned_text = cleaned_text.lower() # 英語 => ひらがな. ex) 'kaげやmay' => {'is_success': False, 'text': 'かげやま'} result = otapick.alphabet2kana(cleaned_text) if result['is_success']: # 全てひらがなの状態 cleaned_text = result['text'] else: # ひらがな変換が失敗し、 cleaned_text = result['text'] # メタ文字(* \ | ? +)をエスケープ meta_char_tuple = ('\\', '*', '+', '.', '?', '{', '}', '(', ')', '[', ']', '^', '$', '-', '|', '/') for meta_char in meta_char_tuple: if meta_char in cleaned_text: cleaned_text = cleaned_text.replace(meta_char, '\\{}'.format(meta_char)) matched_members = Member.objects.filter( Q(full_kana__iregex=r'^%s' % cleaned_text) | Q(first_kana__iregex=r'^%s' % cleaned_text) | Q(full_kanji__iregex=r'^%s' % cleaned_text) | Q(first_kanji__iregex=r'^%s' % cleaned_text) | Q(full_eng__iregex=r'^%s' % cleaned_text) | Q(first_eng__iregex=r'^%s' % cleaned_text)) matched_member_keywords = MemberKeyword.objects.filter( keyword__iregex=r'^%s' % cleaned_text) # keywordもマッチした場合 if matched_member_keywords.count() > 0: matched_member_pk_list = [ matched_member.pk for matched_member in matched_members ] matched_keyword_member_pk_list = [ matched_member_keyword.member.pk for matched_member_keyword in matched_member_keywords ] member_pk_list = list( set(matched_member_pk_list + matched_keyword_member_pk_list)) # 重複を削除 members = Member.objects.filter(pk__in=member_pk_list) else: members = matched_members if members.exists(): return members else: return
def _extract_lemmatized_word( word_info, use_jaconv=False, pos_list=[], exclude_numbers=False, exclude_symbols=False ): word_info = word_info.split('\t') if len(word_info) > 1: word_details = word_info[1].split(',') if pos_list != [] and word_details[0] not in pos_list: return '' if exclude_numbers and word_details[1] == '数': return '' if exclude_symbols and word_details[0] == '記号': return '' if len(word_details) > 6 and word_details[6] != '*': word = word_details[6] else: word = word_info[0] else: word = word_info[0] if use_jaconv: word = jaconv.z2h(word, digit=True, ascii=True) word = jaconv.normalize(word) return word
def find_header_end(): for ri, r in enumerate(bulk): cs = [jaconv.normalize(c).replace(" ","") for ci, c in enumerate(r)] if "開始" in cs and "終了" in cs: return ri if "開始時間" in cs and "終了時間" in cs: return ri
def normalize_line(line): half = jaconv.z2h(jaconv.normalize(line), kana=False, digit=True, ascii=True) stripped = half.strip() dashed = dash_re.sub('-', stripped) return ws_re.sub(' ', dashed)
def normalize_surface(self, line, idx_surface=None): s = line[idx_surface] s = unicodedata.normalize("NFKC", s) s = s.upper() s = jaconv.normalize(s, "NFKC") s = jaconv.h2z(s, digit=True, ascii=True, kana=True) s = s.replace("\u00A5", "\uFFE5") # yen symbol line[idx_surface] = s return line
def g2p(text, trans_type="char"): text = jaconv.normalize(text) if trans_type == "char": text = pyopenjtalk.g2p(text, kana=True) elif trans_type == "phn": text = pyopenjtalk.g2p(text, kana=False) else: assert False return text
def test_regex_3(self): text = "豪華で美しいホテル" text = jaconv.normalize(text) nlp = spacy.load("ja_ginza") doc = nlp(text) chunks = [] for chunk_doc, _ in ja_pos_regex_matches( doc, compiled=COMPILED_CHUNKS_PATTERN): chunks.append(chunk_doc.text) expect = ['豪華で美しいホテル'] self.assertEqual(chunks, expect)
def normalize_hiragana(s): s = jaconv.normalize(s, 'NFKC') s = re.sub('う ゙', 'ぶ', s) s = re.sub(r'(.)ゝ', r'\1\1', s) s = re.sub(r'(.)ゞ', lambda m: m[1] + HIRAGANA_DAKUON_MAP[m[1]], s) ps = s while True: s = s.translate(HIRAGANA_NORMALIZER) if ps == s: break ps = s return s
def test_regex_for_verb_phrase_5(self): text = "彼はこの本を注意深く読んだ" text = jaconv.normalize(text) nlp = spacy.load("ja_ginza") doc = nlp(text) chunks = [] for chunk_doc, _ in ja_pos_regex_matches( doc, compiled=COMPILED_CHUNKS_PATTERN): chunks.append(chunk_doc.text) expect = ['彼', 'は', 'この本', 'を', '注意深く読んだ'] self.assertEqual(chunks, expect)
def optimize_text(_text): """文字列を「半角 & ひらがな & 英語小文字」に最適化""" # 全角 ⇒ 半角 & ノーマライズ. ex) 'kAげヤmay' => 'kAげヤmay' cleaned_text = jaconv.normalize(_text, "NFKC") # カタカナ => ひらがな. ex) 'kAげヤmay' => 'kAげやmay' cleaned_text = jaconv.kata2hira(cleaned_text) # 大文字 => 小文字. ex) 'kAげやmay' => 'kaげやmay' cleaned_text = cleaned_text.lower() return cleaned_text
def test_regex(self): text = "アジアのバー・パブ・クラブショップ" text = jaconv.normalize(text) nlp = spacy.load("ja_ginza") doc = nlp(text) chunks = [] for chunk_doc, _ in ja_pos_regex_matches( doc, compiled=COMPILED_CHUNKS_PATTERN): chunks.append(chunk_doc.text) expect = ['アジア', 'の', 'バー・パブ・クラブショップ'] self.assertEqual(chunks, expect)
def score(self, X, y=None): """ Follow this previous steps: 2. Apply beam search with its corresponding parameters """ mapping_inout = load_data_from_ocr(ocr_output_src_folder) preds = [] lbls = [] for input_fn, lbl in mapping_inout.items(): ctc_logit_matrix = np.load(input_fn) predict = self.predict(ctc_logit_matrix) preds += [jaconv.normalize(predict)] lbls += [jaconv.normalize(lbl)] """ 3. Return the accuracy by character, exact match """ acc_by_char, em = calculate_accuracy(preds, lbls) return em
def from_sentence(klass, sentence: str, mecab: MeCab) -> 'Iterable[Word]': normalized = jaconv.normalize(sentence) for mec_node in mecab.parse(normalized, as_nodes=True): if mec_node.is_eos(): break res = AnalyzeMorp(mec_node) if res.is_symbol(): continue if TagWord.is_include(res.surface()): yield TagWord(res.surface()) else: yield Word(surface=res.surface(), yomi=res.yomi())
def text_to_sequence(text, p=0.0): for c in [" ", " ", "「", "」", "『", "』", "・", "【", "】", "(", ")", "(", ")"]: text = text.replace(c, "") text = text.replace("!", "!") text = text.replace("?", "?") text = normalize_delimitor(text) text = jaconv.normalize(text) if p > 0: text = mix_pronunciation(text, p) text = jaconv.hira2kata(text) text = add_punctuation(text) return [ord(c) for c in text] + [_eos] # EOS
def _normalize_text(text): """Remove unusual characters from the ocr results :param text: ocr result need to be fix :returns: normalized string :rtype: string """ if pd.isna(text): return "" text = unicodedata.normalize('NFKC', str(text)) text = jaconv.normalize(text, 'NFKC') text = "".join(text.split()) return text
def kataconv(content): try: #Disable mecab by commenting the following 3 lines kanji = input("Convert kanji?: ") if kanji == "Y"or kanji == "y" or kanji == "y" or kanji == "Y": content = mecab.parse(content) content = content.replace("\n","") content = content.replace("‖"," "*32)#act as enter, change num here to fit content = jaconv.normalize(content) content = jaconv.z2h(content) content = jaconv.hira2hkata(content) print("Output content: "+content) return content except Exception as error: print(error)
def sy2a(self, s, y): # preprocess strings s = s.strip() y = jaconv.normalize(y, "NFKC") y = jaconv.hira2kata(y) # encode s_np, y_np = self.encode_sy(s, y) s_np, y_np = self.add_batch_dim(s_np, y_np) # inference accent = self.infer(s_np, y_np)[0] yomi_and_accent = self.zip_ya(y, accent) return yomi_and_accent
def text_to_sequence(text, index, mix=False): for c in [" ", " ", "「", "」", "『", "』", "・", "【", "】", "(", ")", "(", ")"]: text = text.replace(c, "") text = text.replace("!", "!") text = text.replace("?", "?") text = normalize_delimiter(text) # text = normalize_number(index, text) text = jaconv.normalize(text) if mix: text = mix_pronunciation(text) text = jaconv.hira2kata(text) text = add_punctuation(text) return [ord(c) for c in text] + [_eos], text
def guess_mapname(ocr_string): ocr_string = jaconv.normalize(ocr_string) print("normalized ocr_string=", ocr_string) #global mapname # mapnames = [ jaconv.normalize(i) for i in mapnames ] mapnames = list_mapname() mapname_normalized2org = {} mapnames_normalized = [] for mapname_org in mapnames: mapname_normalized = jaconv.normalize( mapname_org ) mapname_normalized2org[mapname_normalized] = mapname_org mapnames_normalized.append( mapname_normalized) #print( " normalized mapnames=", mapnames_normalized ) min_value = 1000 min_map = None for normalized_map in mapnames_normalized: value = editdistance.eval( normalized_map, ocr_string ) if value < min_value: min_value = value min_map = normalized_map print( min_map, " value=", min_value ) #return min_map return mapname_normalized2org[ min_map ]
def normalize_string(string): ''' normalize string. Half-width katakana -> Full-width katakana Full-width digit -> Half-width digit etc. Args: string: input string Returns: normalized string ''' normalized = jaconv.normalize(string) return normalized
revstrng = 'Testing automation with Selenium in Python' test_rev_string(revstrng) time.sleep(5) driver.find_element_by_id('jp_lang').click() time.sleep(3) driver.switch_to.alert.send_keys('ショーン') time.sleep(3) driver.switch_to.alert.accept() time.sleep(3) numbuttonsjp = numbuttons//2 for x in range(numbuttonsjp, numbuttons): print(jaconv.normalize(buttons[x].text, 'NFKC')) time.sleep(7) driver.find_element(By.XPATH, '//button[text()="Projects Top"]').click() time.sleep(3) driver.find_element_by_id('Japan_Packing').click() time.sleep(5) packing_list_divs = driver.find_elements_by_tag_name('div') packing_list_buttons = driver.find_elements_by_tag_name('button') numbuttons = len(packing_list_buttons) for x in range(1, numbuttons): driver.find_element_by_xpath('//button[text()="' + packing_list_buttons[x].text + '"]').click() time.sleep(1)
def test_normalize(): assert_equal(jaconv.normalize('ティロ・フィナ〜レ', 'NFKC'), 'ティロ・フィナーレ') assert_equal(jaconv.normalize(_concat(HALF_KANA, FULL_DIGIT), 'NFKC'), ''.join(FULL_KANA) + ''.join(HALF_DIGIT))
if i==0 and len(ks)==0: es = re.sub("\s*","", es) g.add((b, NS1["地区"], rdflib.Literal(es))) elif ks in ("バス送迎", "一時保育"): m = re.match("["+MARU+"]([(\(](?P<note>.*)[\))])?", es) if m: s = rdflib.BNode(name+ks) g.add((b, NS1["service"], s)) g.add((s, NS1["type"], rdflib.Literal(ks))) if m.group("note"): g.add((s, NS1["備考"], rdflib.Literal(m.group("note")))) else: assert not es, es elif ks == "電話番号": es = jaconv.normalize(es) m1 = re.match("(\d+)\-(\d+)-(\d+)", es) m2 = re.match("(\d+)\-(\d+)", es) if m1: p = es elif m2: p = "079-"+es else: raise ValueError(es) g.add((b, NS1[ks], rdflib.Literal(p))) elif ks=="施設名": m = re.search("(※[\d1234567890]*)$", es) if m: h = m.group(1) for si in table.xpath("following-sibling::*"):
async def submit_attack_log(message, orig_user): global Boss_Round_Count msg_content = jaconv.normalize(message.content) # 凸登録 if re.match(r'^[1-5][物魔bm]', msg_content): # ボス凸先 boss = int(msg_content[0]) # 物魔判定 atk_type_m = False if msg_content[1] == '魔' or msg_content[1] == 'm': atk_type_m = True # 通知設定判定 is_req = False if re.match(r'^[1-5][物魔bm][1-5]', msg_content): is_req = True # 〆判定 is_finished = False if re.match(r'^[1-5][物魔bm][ー〆-]', msg_content): is_finished = True # 通知設定判定 req_boss = 0 # 通知対象記録 is_timed = False # 持越時間判定 int_time = 0 # 持越時間 if is_finished or is_req: is_this_boss = True for i in msg_content: # ボス番号読み取って該当ボスのフラグを立てる if not is_timed and not is_this_boss and '0' < i < '6': req_boss |= 2**(int(i) - 1) if not is_timed and is_this_boss and '0' < i < '6': is_this_boss = False # 最初の数字は凸対象ボスだから無視 # @以降は持越時間表記として読取 if not is_timed and i == '@': is_timed = True if is_timed and re.match('\d', i): int_time *= 10 int_time += int(i) # メンションかs検知したらそこで通知判定終了 if (is_timed and i == 's') or i == '<': break for p in playerData: if p.user == orig_user: break else: reply = f'{orig_user.display_name}さんはリストに入っていません' await reply_and_delete(message, reply, DELAY_S) # リストから探して対象のログを更新 for p in playerData: if p.user == orig_user: # 3凸済の場合は更新拒否 if p.done_cnt == 3: reply = f'{p.user.display_name}さんは本日既に3凸済です' await reply_and_delete(message, reply, DELAY_S) return # ログバックアップ p.backup_play_log() # カウント数バックアップ done_today = p.done_cnt # 持越消化凸か確認 is_rolled = False txt_rolled = '' txt_finished = '' if p.req_none_rolled or (p.req_list and not p.notice_req): is_rolled = True txt_rolled = '持越分' # 持越で〆たら持越発生なし if is_finished and is_rolled: txt_finished = ' 持越で〆たため、持越発生なし' # 持越で〆なければ持越発生 if is_finished and not is_rolled: txt_finished = ' ' + str(boss) + 'ボスで持越発生' # 持越発生編成を記録 if atk_type_m: p.rolled_type = '魔法' else: p.rolled_type = '物理' # 時間入力がある場合は時間も記録 if int_time: txt_finished += str(int_time) + '秒' p.rolled_time = int_time # 凸登録処理 p.add_atk(boss) # 翌周に来たか global Is_Boss_Round_End if Is_Boss_Round_End: Boss_Round_Count += 1 Is_Boss_Round_End = False # 直近のボスを記録 global Recent_Boss Recent_Boss = str(boss) + 'ボス' if is_finished: Recent_Boss += '〆' # 5〆で次周 if boss == 5: Is_Boss_Round_End = True p.recent_boss = Recent_Boss # 通常凸と持越で〆た場合は凸カウント if not is_finished or (is_finished and is_rolled): p.rolled_time = 0 p.rolled_type = '' if atk_type_m: p.add_atk_cnt_m() else: p.add_atk_cnt_b() # 3凸未完了で通知希望がある場合、通知設定 if req_boss and p.done_cnt < 3: p.req_list = req_boss # 通常凸及び〆で持越使用時は凸希望扱い if not is_finished or (is_finished and is_rolled): p.notice_req = True # ボス希望〆なしの場合、持越先指定なしフラグを立てる if is_finished and not is_rolled and not req_boss: p.req_none_rolled = True reply = f'{p.user.display_name}さんの{boss}ボス凸({done_today + 1}凸目{txt_rolled})確認{txt_finished}' await reply_and_delete(message, reply, DELAY_S) # 〆たら次ボス待機者チェック if is_finished: reply = '' rolled_target = '' # 持越中通知 notice_target = '' # 通知対象 next_boss = boss + 1 # 5の次は1 if 5 < next_boss: next_boss = 1 # 通知希望者を探してリストアップ for p in playerData: if p.is_req_boss(next_boss) and not p.notice_req: rolled_target += p.user.mention if p.is_req_boss(next_boss) and p.notice_req: notice_target += p.user.mention # 待機者が居たら通知 if rolled_target: reply += f'{rolled_target} {next_boss}ボスで持越使えるよー!起きてー!起きてー!\n' if notice_target: reply += f'{notice_target} {next_boss}ボスの時間だよー!\n' if reply: await message.channel.send(reply)
async def on_message(message): global Message_Log_Main global Message_Log_Incomplete global Message_Log_Request global Flg_Sleep global Flg_Demo global Flg_No_Emoji global Flg_Setup global ID_ROLE_ADMIN global ID_CHANNEL_MAIN global ID_CHANNEL_LOG_MAIN global ID_CHANNEL_LOG_INCOMPLETE global ID_CHANNEL_LOG_REQUEST global ID_CHANNEL_REACT global ID_EMOJI global Orig_Channel_ID Orig_Channel_ID = message.channel.id msg_content = jaconv.normalize(message.content) # 代筆時以外の自分自身には無反応 if message.author.id == client.user.id and not message.mentions: return # 持越時間予想 if re.match(r'^持越時間|^持越し時間|^持ち越し時間|^rollover|^ro', msg_content): await rollover_simulate(message, msg_content) return # コマンド入力チャンネルが指定されている場合、指定チャンネル以外は無反応 if ID_CHANNEL_MAIN is not None and message.channel != client.get_channel( ID_CHANNEL_MAIN): return # 飼い主か確認(飼い主未設定の場合、全員飼い主とみなす) is_admin = False if ID_ROLE_ADMIN is None: is_admin = True for r in message.author.roles: if r.id == ID_ROLE_ADMIN: is_admin = True # 休眠機能 if is_admin and re.match(r'sleep$|/sleep$', msg_content): if Flg_Sleep: Flg_Sleep = False reply = f'休眠解除しました。' await reply_and_delete(message, reply, DELAY_S) else: Flg_Sleep = True reply = f'休眠に入ります。' await reply_and_delete(message, reply, DELAY_S) # 休眠判定 if Flg_Sleep: return # デモモード機能 if is_admin and re.match(r'demo$|/demo$', msg_content): if Flg_Demo: Flg_Demo = False reply = f'デモモード解除しました。' await reply_and_delete(message, reply, DELAY_S) else: Flg_Demo = True reply = f'デモモードに入ります。' await reply_and_delete(message, reply, DELAY_S) # 飼い主かBOT自身がメンションしてたら代筆機能 orig_user = message.author if (is_admin and message.mentions) or (message.author.id == client.user.id and message.mentions): orig_user = message.mentions[0] # ヘルプ if re.match(r'help$|/help$|ジュウシマツの使い方$', msg_content): reply = f'```\n' reply += '(持越時間 or 持越し時間 or 持ち越し時間 or rollover or ro)(現在のボスHP)\n\t持越時間に対して必要なダメージを計算する\n\t例:持越時間 250\n\n' reply += '(持越時間 or 持越し時間 or 持ち越し時間 or rollover or ro)(現在のボスHP)-(ダメージ)\n\tダメージから予想される持越時間を計算する\n\t例:持越時間 250-600\n\n' reply += '(ボス番号)(物 or 魔 or b or m)\n\tボス凸履歴を登録\n\t例:1物 3b 5m\n\n' reply += '(ボス番号)(物 or 魔 or b or m)(通知希望のボス番号)\n\t' \ 'ボス凸履歴を登録すると同時に、希望ボスまで来たら通知設定\n\t例:1物135 1m135(1ボス凸+1,3,5ボスが回ってきたら通知)\n\n' reply += '(ボス番号)(物 or 魔 or b or m)(〆 or -)\n\tボス撃破履歴を登録\n\t例:3魔〆 5m-\n\n' reply += '(ボス番号)(物 or 魔 or b or m)(〆 or -)(持越先として通知希望のボス番号)\n\t' \ 'ボス撃破履歴を登録すると同時に、討伐時に通知設定\n\t例:1物〆135 1m-135(1ボス撃破+1,3,5ボスが回ってきたら通知)\n\n' reply += '(ボス番号)(物 or 魔 or b or m)(〆 or -)(持越先ボス番号)(@秒数s)\n\t' \ 'ボス撃破履歴を登録すると同時に、討伐時に通知設定し、残り秒数を登録\n\t例:2物〆135@50s(135で通知、残り50s) 5m-5@90s(5で通知、残り90s)\n\n' reply += 'kd or killed or /killed or タスキル済\n\t今日のタスキル使用を登録\n\n' reply += 'nt(ボス番号) or notice(ボス番号) or /notice(ボス番号) or ボス通知(ボス番号)\n\t' \ 'そのボスの番が来たら通知(持越希望先もこのコマンドで変更可)\n\t' \ '例:/notice 135 で1 3 5ボス到達で通知\n\t/notice (指定なし)で現在設定している通知設定を解除\n\n' reply += 'rt(持越時間) or rolled(持越時間) or /rolled(持越時間) or 持越(持越時間)\n\t' \ '持越時間の事後登録、もしくは変更\n\t' \ '例:/rolled 90 で90秒の持越時間を登録\n\t/rolled (指定なし)で現在登録している持越時間を削除\n\n' reply += 'rv or revert or /revert or 元に戻す \n\t凸リストをひとつ前の状態に戻す\n\n' reply += 'cl or clear or /clear or 凸リストをクリア \n\t凸リストをクリアする\n\n' reply += 'la or list-all or /list-all or 凸リストを表示 \n\tクラン全体の凸状況を表示する\n\n' reply += 'li or list or /list or 未凸リストを表示 \n\tクラン全体の未凸者一覧を表示する\n\n' reply += 'wl or waitlist or /waitlist or ウェイトリストを表示 \n\t持越中もしくは通知登録者一覧を表示する\n\n' reply += 'add or /add\n\tメンバーリストに自分を追加\n\n' reply += '```' await reply_and_delete(message, reply, DELAY_L) return # adminヘルプ if re.match(r'help-admin$|/help-admin$', msg_content): reply = f'```\n管理用コマンド一覧\n\n' reply += 'add @メンバー or /add @メンバー or メンバーを追加 @メンバー \n\t指定したメンバーをリストに追加(纏めてのメンションやロール指定可能)\n\n' reply += 'memberlist or /memberlist or メンバーリストを表示 \n\t登録されているメンバーの一覧表示\n\n' reply += 'ボス凸履歴登録記法 + メンション\n\tボス凸登録代筆(飼い主のみ実行可能)\n\t' \ '例: 1物〆135@90s @ジュウシマツ住職(住職代筆で1ボス〆持越先135、物理編成90秒)\n\n' reply += 'correct or /correct\n\t周回数を訂正する(飼い主のみ実行可能)\n\t例: /correct 50\n\n' reply += 'remove @メンバー or /remove @メンバー\n\t指定したメンバーをリストから削除(飼い主のみ実行可能)\n\n' reply += 'sleep or /sleep\n\t休眠状態を切り替える。(飼い主のみ実行可能)\n\n' reply += '凸リストを全てクリア\n\tメンバーの凸状況を全てクリアする(飼い主のみ実行可能) \n\n' reply += 'メンバーリストをクリア\n\tメンバーリスト・凸状況をクリアする(飼い主のみ実行可能)\n\n' reply += '入力チャンネル設定\n\tコマンド入力を受け付けるチャンネルの指定(飼い主のみ実行可能)\n\t' reply += '例: 入力チャンネル設定 #凸報告用\n\n' reply += '凸進捗リストチャンネル設定\n\t凸進捗を出力するチャンネルの指定(飼い主のみ実行可能)\n\t' reply += '例: 凸進捗リストチャンネル設定 #凸進捗リスト\n\n' reply += '凸未完了リストチャンネル設定\n\t凸未完了者一覧を出力するチャンネルの指定(飼い主のみ実行可能)\n\t' reply += '例: 凸未完了リストチャンネル設定 #3凸未完了リスト\n\n' reply += '通知リストチャンネル設定\n\t持越・通知登録者一覧を出力するチャンネルの指定(飼い主のみ実行可能)\n\t' reply += '例: 通知リストチャンネル設定 #持越中・通知登録リスト\n\n' reply += '絵文字設定\n\t簡易入力用の絵文字の指定(飼い主のみ実行可能)\n\t' reply += '例: 絵文字設定 (絵文字)(絵文字)(絵文字)(絵文字)(絵文字)\n\t' reply += "※ 前から順に物理凸、物理〆、魔法凸、魔法〆、通知登録用の合計5つの絵文字を入力してください\n" reply += '簡易入力チャンネル設定\n\t簡易入力を受け付けるチャンネルの指定(飼い主のみ実行可能)\n\t' reply += '例: 簡易入力チャンネル設定 #簡易入力\n\n' reply += '飼い主設定\n\t飼い主ロールの指定(飼い主のみ実行可能)\n\t' reply += '例: 飼い主設定 @飼い主\n\t' reply += '※ 飼い主未設定の場合、誰でも飼い主権限コマンドが実行可能です\n\t' reply += '※ ロールをメンション出来ない、メンションする方法が判らない場合:\n\t\t' reply += 'ロール->ロール設定->このロールに対して@mentionを許可するを設定してください \n\n' reply += '```' await reply_and_delete(message, reply, DELAY_L) return # 飼い主設定 if is_admin and re.match(r'^飼い主設定', msg_content): if message.role_mentions: ID_ROLE_ADMIN = message.role_mentions[0].id reply = message.role_mentions[0].name reply += 'を飼い主として設定しました' await reply_and_delete(message, reply, DELAY_S) else: reply = 'ロールがメンションされていません\n\t' reply += '※ ロールをメンション出来ない、メンションする方法が判らない場合:\n\t\t' reply += 'ロール->ロール設定->このロールに対して@mentionを許可するを設定してください \n\n' await reply_and_delete(message, reply, DELAY_L) return # コマンド入力チャンネル設定 if is_admin and message.content.startswith('入力チャンネル設定'): if message.channel_mentions: ID_CHANNEL_MAIN = message.channel_mentions[0].id reply = message.channel_mentions[0].name reply += 'チャンネルをコマンド入力用に設定しました' await reply_and_delete(message, reply, DELAY_S) else: reply = 'チャンネルがメンションされていません' await reply_and_delete(message, reply, DELAY_S) # 進捗リスト出力チャンネル設定 if is_admin and message.content.startswith('凸進捗リストチャンネル設定'): if message.channel_mentions: ID_CHANNEL_LOG_MAIN = message.channel_mentions[0].id reply = message.channel_mentions[0].name reply += 'チャンネルを凸進捗リストの出力用に設定しました' Message_Log_Main = None # 凸進捗出力メッセージオブジェクト await reply_and_delete(message, reply, DELAY_S) else: reply = 'チャンネルがメンションされていません' await reply_and_delete(message, reply, DELAY_S) # 凸未完了リスト出力チャンネル設定 if is_admin and message.content.startswith('凸未完了リストチャンネル設定'): if message.channel_mentions: ID_CHANNEL_LOG_INCOMPLETE = message.channel_mentions[0].id reply = message.channel_mentions[0].name reply += 'チャンネルを凸未完了者リストの出力用に設定しました' Message_Log_Incomplete = None # 凸未完了者リスト出力メッセージオブジェクト await reply_and_delete(message, reply, DELAY_S) else: reply = 'チャンネルがメンションされていません' await reply_and_delete(message, reply, DELAY_S) # 通知リスト出力チャンネル設定 if is_admin and message.content.startswith('通知リストチャンネル設定'): if message.channel_mentions: ID_CHANNEL_LOG_REQUEST = message.channel_mentions[0].id reply = message.channel_mentions[0].name reply += 'チャンネルを持越・通知希望リストの出力用に設定しました' Message_Log_Request = None # 持越中・通知登録者リスト出力メッセージオブジェクト await reply_and_delete(message, reply, DELAY_S) else: reply = 'チャンネルがメンションされていません' await reply_and_delete(message, reply, DELAY_S) # 簡易コマンドリアクション用絵文字設定 if is_admin and message.content.startswith('絵文字設定'): tmp_emojis = re.findall(r'<:\w*:\d*>', message.content) tmp_emojis = [ int(e.split(':')[2].replace('>', '')) for e in tmp_emojis ] if len(tmp_emojis) < 5: reply = '設定する絵文字の数が足りません\n' reply += '例: 絵文字設定 (絵文字)(絵文字)(絵文字)(絵文字)(絵文字)\n\t' reply += "※ 前から順に物理凸、物理〆、魔法凸、魔法〆、通知登録用の合計5つの絵文字を入力してください\n" await reply_and_delete(message, reply, DELAY_S) elif len(tmp_emojis) == 5: ID_EMOJI = tmp_emojis reply = '簡易入力用絵文字を設定しました' await reply_and_delete(message, reply, DELAY_S) else: for i in range(5): ID_EMOJI[i] = tmp_emojis[i] reply = '簡易入力用絵文字を設定しました' await reply_and_delete(message, reply, DELAY_S) # 簡易コマンドリアクション用チャンネル設定 if is_admin and message.content.startswith('簡易入力チャンネル設定'): if message.channel_mentions: ID_CHANNEL_REACT = message.channel_mentions[0].id # リアクションメッセージ設定 await init_react_channel() reply = message.channel_mentions[0].name reply += 'チャンネルを簡易リアクション用に設定しました' await reply_and_delete(message, reply, DELAY_S) else: reply = 'チャンネルがメンションされていません' await reply_and_delete(message, reply, DELAY_S) # 絵文字設定済か確認 Flg_No_Emoji = False for emoji_id in ID_EMOJI: if emoji_id is None: Flg_No_Emoji = True # 初期設定 if ID_CHANNEL_MAIN and ID_CHANNEL_LOG_MAIN and ID_CHANNEL_LOG_INCOMPLETE \ and ID_CHANNEL_LOG_REQUEST and ID_CHANNEL_REACT and not Flg_No_Emoji: Flg_Setup = False else: Flg_Setup = True await setup_wizard(message) return # メンバーリストに追加 if re.match(r'^add|^/add|^メンバーを追加', msg_content): if message.role_mentions: # ロールがメンションされていれば、ロールのメンバーを追加 member_list = message.role_mentions[0].members elif message.mentions: # リプがあればリプ対象を追加 member_list = message.mentions else: # リプがなければ送信主を追加 member_list = [message.author] reply = '' for i in member_list: # 登録済みか確認し、登録されてたらスキップ is_matched = False for p in playerData: if i == p.user: is_matched = True reply += f'{i.display_name}の事は既に知っているぜ\n' if not is_matched: playerData.append( PlayerData(i, 0, 0, 0, 0, False, False, False, 0, 0, '', '')) reply += f'{i.display_name}さんをメンバーリストに追加\n' await reply_and_delete(message, reply, DELAY_S) return # メンバーリスト表示 if re.match(r'ml$|memberlist$|/memberlist$|メンバーリストを表示$', msg_content): reply = f'```\n' for p in playerData: reply += f' {p.user.display_name} \n' reply += f'```' await reply_and_delete(message, reply, DELAY_M) return # ボス通知登録 if re.match(r'^nt|^notice|^/notice|^ボス通知', msg_content): # ボスフラグ生成 req_boss = 0 for i in msg_content: if '0' < i < '6': req_boss |= 2**(int(i) - 1) elif i == '@': break # 対象をリストから探す for p in playerData: if p.user == orig_user and p.done_cnt != 3: # ログバックアップ p.backup_play_log() # 有効なボス引数があれば上書き if req_boss: # 持越先希望じゃなくて凸希望登録の場合は、凸希望登録フラグを立てる(初回のみでいい) if not p.notice_req and not p.req_none_rolled and not p.req_list: p.notice_req = True # 書込み p.req_none_rolled = False p.req_list = req_boss reply = f'{p.user.display_name}さんのボス通知希望を確認' await reply_and_delete(message, reply, DELAY_S) # 指定なしで通知解除 else: if not p.notice_req and p.req_list: p.req_none_rolled = True p.req_list = 0 p.notice_req = False reply = f'{p.user.display_name}さんのボス通知希望を解除しました' await reply_and_delete(message, reply, DELAY_S) elif p.user == orig_user and p.done_cnt == 3: reply = f'{p.user.display_name}さんは本日既に3凸済です' await reply_and_delete(message, reply, DELAY_S) return # ボス通知追加 if re.match(r'^通知追加', msg_content): # ボスフラグ生成 req_boss = 0 for i in msg_content: if '0' < i < '6': req_boss |= 2**(int(i) - 1) elif i == '@': break # 対象をリストから探す for p in playerData: if p.user == orig_user and p.done_cnt != 3: # ログバックアップ p.backup_play_log() # 有効なボス引数があれば追加 and_tmp = req_boss & p.req_list if req_boss and not and_tmp: # 持越先希望じゃなくて凸希望登録の場合は、凸希望登録フラグを立てる(初回のみでいい) if not p.notice_req and not p.req_none_rolled and not p.req_list: p.notice_req = True # 書込み p.req_none_rolled = False p.req_list |= req_boss reply = f'{p.user.display_name}さんのボス通知希望を確認' await reply_and_delete(message, reply, DELAY_S) # 指定なしで通知解除 elif req_boss and and_tmp: if not p.notice_req and p.req_list and not p.req_list ^ req_boss: p.req_none_rolled = True p.req_list = p.req_list ^ req_boss if p.req_list: p.notice_req = False reply = f'{p.user.display_name}さんのボス通知希望を解除しました' await reply_and_delete(message, reply, DELAY_S) elif p.user == orig_user and p.done_cnt == 3: reply = f'{p.user.display_name}さんは本日既に3凸済です' await reply_and_delete(message, reply, DELAY_S) return # 持越時間設定 if re.match(r'^rt|^rolled|^/rolled|^持越', msg_content): for p in playerData: if p.user == orig_user and p.rolled_type: # ログバックアップ p.backup_play_log() tmp_rolled_time = 0 is_rolled_time = False for i in msg_content: if re.match('\d', i): is_rolled_time = True tmp_rolled_time = tmp_rolled_time * 10 + int(i) elif is_rolled_time and i == "<": break if tmp_rolled_time == 0: p.rolled_time = 0 reply = f'{orig_user.display_name}さんの持越時間登録を削除しました' elif tmp_rolled_time < 20: reply = f'持越時間が短すぎます' elif 20 <= tmp_rolled_time <= 90: p.rolled_time = tmp_rolled_time reply = f'{orig_user.display_name}さんの持越時間を登録しました' elif 90 < tmp_rolled_time: reply = f'持越時間が長すぎます' else: reply = f'持越登録に失敗しました' await reply_and_delete(message, reply, DELAY_S) elif p.user == orig_user: reply = f'{orig_user.display_name}さんは持越していません' await reply_and_delete(message, reply, DELAY_S) return # タスキル済 if re.match(r'^kd|^killed|^/killed|^タスキル済', msg_content): for p in playerData: if p.user == orig_user: # ログバックアップ p.backup_play_log() p.task_killed = True reply = f'{orig_user.display_name}さんのタスキルを確認' await reply_and_delete(message, reply, DELAY_S) return # 凸リスト表示 if re.match(r'la$|list-all$|/list-all$|凸リストを表示$', msg_content): reply = f'```\n' reply += await get_attack_log(0) reply += f'```' await reply_and_delete(message, reply, DELAY_M) return # 未凸リスト表示 if re.match(r'li$|list$|/list$|未凸リストを表示$', msg_content): reply = f'```\n未凸者リスト\n\n' reply += await get_attack_log(1) reply += f'```' await reply_and_delete(message, reply, DELAY_M) return # ウェイトリスト表示 if re.match(r'wl$|waitlist$|/waitlist$|ウェイトリストを表示$', msg_content): reply = f'```\n持越・通知登録リスト\n\n' reply += await get_attack_log(2) reply += f'```' await reply_and_delete(message, reply, DELAY_M) return # 直近の変更を元に戻す if re.match(r'^rv|^revert|^/revert|^元に戻す', msg_content): for p in playerData: if p.user == orig_user: try: p.revert_play_log() reply = f'{orig_user.display_name}さんの凸リストを元に戻しました。' except IndexError: reply = f'{orig_user.display_name}さんの凸履歴はありません。' await reply_and_delete(message, reply, DELAY_S) return # 凸リストクリア if re.match(r'^cl|^clear|^/clear|^凸リストをクリア', msg_content): for p in playerData: if p.user == orig_user: # ログバックアップ p.backup_play_log() p.erase_all() reply = f'{orig_user.display_name}さんの凸リストをクリアしました。' await reply_and_delete(message, reply, DELAY_S) return # 凸リストを全てクリア if is_admin and msg_content == '凸リストを全てクリア': for p in playerData: p.erase_all() p.erase_backup() Message_Log_Main = None reply = f'凸リストを全てクリアしました' await reply_and_delete(message, reply, DELAY_S) return # メンバーリストクリア if is_admin and msg_content == 'メンバーリストをクリア': playerData.clear() Message_Log_Main = None reply = f'メンバーリストをクリアしました' await reply_and_delete(message, reply, DELAY_S) return # 対象をメンバーリストからクリア if is_admin and re.match(r'^remove|^/remove', msg_content): # リプがあればリプ対象を追加、リプがなければ送信主を追加 if message.mentions: remove_user = message.mentions[0] else: remove_user = message.author if remove_user: # 登録済みか確認し、登録されてたら終了 for p in playerData: if remove_user == p.user: playerData.remove(p) reply = f'{remove_user.display_name}さんをリストから削除しました' await reply_and_delete(message, reply, DELAY_S) return reply = f'{remove_user.display_name}さんはリストに載っていません' await reply_and_delete(message, reply, DELAY_S) return # 周回数修正 global Boss_Round_Count if is_admin and re.match(r'^correct|^/correct', msg_content): Boss_Round_Count = 0 for i in msg_content: if re.match('\d', i): Boss_Round_Count *= 10 Boss_Round_Count += int(i) reply = f'周回数を修正しました' await reply_and_delete(message, reply, DELAY_S) return # 凸登録 await submit_attack_log(message, orig_user)
def normalize(cls, text): text = jaconv.normalize(text=text.strip()) return text
def capture(g, page, idx, data, info): try: notes = {p["key"]:p["value"] for p in info if int(p["page"])==page and p["key"].startswith("※")} except: notes = {} for r in data: line = "".join(r) if not line or line[0] in "※*" or line.startswith("備考"): continue obj = dict(zip(idx, r)) R = BNode(obj["施設名"]) azukari = None skip = [] for i, v in enumerate(r): k = idx[i] if k in ("所在区","施設名","所在地"): m = re.match("(.*)(※[1234567890]*)", v) if m: v = m.group(1) n = notes.get(m.group(2)) if n: g.add((R, NS1[k+"_備考"], Literal(n))) else: raise ValueError([page, info]) g.add((R, NS1[k], Literal(v))) elif k == "分類": m = re.match("^(?P<institute>.*?)([\((](?P<finance>.*)[\))])?$", v) if m: g.add((R, NS1["分類"], Literal(m.group("institute")))) if m.group("finance"): g.add((R, NS1["財政措置"], Literal(m.group("finance")))) else: raise ValueError(v) elif k == "電話番号": for d in DASH: v = v.replace(d, "-") m = re.match("^\d{3}-\d{4}$", v) if m: g.add((R, NS1["電話番号"], Literal("078-"+v))) elif v: raise ValueError(json.dumps(v)) elif k == "組織": m = re.match("^[\((](?P<le>\w+)[\))]$", v) if m: # legal entity g.add((R, NS1["組織"], Literal(m.group("le")))) else: print(info, line, obj) raise ValueError(json.dumps(v)) elif k.startswith("認可定員"): if v: try: int(v) g.add((R, NS1["認可定員"], Literal(v))) except: raise ValueError(json.dumps(v)) elif k.startswith("受入開始年齢"): v = jaconv.normalize(v) m = re.match("\d+歳", v) if v: if not m: assert v in MARU, json.dumps(v) v = "3歳" if re.match("受入開始年齢 (歳満[~ー][33]|満[33]歳[~ー])", k): v = "満"+v elif re.match("受入開始年齢 ([~ー][33]歳|[33]歳[~ー])", k): pass else: raise ValueError(json.dumps(k)) g.add((R, NS1["受入開始年齢"], Literal(v))) elif k.startswith("預かり保育"): v = jaconv.normalize(v) m = re.match("\d+:\d{2}", v) if m: S = azukari if azukari is None: azukari = S = BNode(obj["施設名"]+"預かり保育") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("預かり保育"))) if re.match("預かり保育 開始時間[\((]朝[\))]", k): g.add((S, NS1["朝_開始時刻"], Literal(v))) elif re.match("預かり保育 終了時間[\((]夕[\))]", k): g.add((S, NS1["夕_終了時刻"], Literal(v))) else: raise ValueError(k) elif v in DASH: pass else: raise ValueError(json.dumps(v)) elif k == "園バス": v = jaconv.normalize(v) if v in DASH: pass else: assert v in MARU, json.dumps(v) S = BNode(obj["施設名"]+"園バス") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("園バス"))) elif k == "給食": v = jaconv.normalize(v) m = re.match("週\d日", v) if m: S = BNode(obj["施設名"]+"給食") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("給食"))) g.add((S, NS1["回数"], Literal(v))) elif v in DASH: pass else: raise ValueError(v) elif k.startswith("未就園児教室"): v = jaconv.normalize(v) m = re.match("(満?\d歳|生後\d+(か|ケ)月)", v) if m: pass elif v == "-": v = None elif v: assert v in MARU, json.dumps(v) if re.match("未就園児教室 受入開始年齢 [11]歳[~ー]", k): v = "1歳" elif re.match("未就園児教室 受入開始年齢 [22]歳[~ー]", k): v = "2歳" assert v not in MARU, k if v: S = BNode(obj["施設名"]+"未就園児教室") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("未就園児教室"))) g.add((S, NS1["受入開始年齢"], Literal(v))) elif k == "園庭開放": v = jaconv.normalize(v) if v == "-": pass elif v: assert v in MARU, json.dumps(v) S = BNode(obj["施設名"]+"園庭開放") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("園庭開放"))) else: print(repr([k,idx])) raise ValueError(json.dumps(k))
def capture(g, page, idx, data, info): slot = None for ri, r in enumerate(data): line = "".join(r) if not line or line[0] in "※*": continue if not "".join(r[1:]): continue if slot is None: slot = r for i,v in enumerate(r): if v: slot[i] = v elif idx[i] in ("区",): r[i] = slot[i] obj = dict(zip(idx, r)) R = BNode(obj["施設名"]) azukari = None skip = [] for i, v in enumerate(r): k = idx[i] if k in ("区","施設名","施設所在地"): if k=="区": k = "所在区" v += "区" elif k=="施設所在地": k = "所在地" g.add((R, NS1[k], Literal(v))) elif k.startswith("募集クラス数"): if not v: continue S = BNode(obj["施設名"]+k) g.add((R, NS1["募集クラス"], S)) try: int(v) g.add((S, NS1["年齢"], Literal(k.split()[1]))) g.add((S, NS1["数"], Literal(v))) except: g.add((S, NS1["備考"], Literal(v))) elif k == "電話番号": v = jaconv.normalize(v) for d in DASH: v = v.replace(d, "-") m = re.match("^\d{3}-\d{4}$", v) if m: g.add((R, NS1["電話番号"], Literal("078-"+v))) elif v: raise ValueError(json.dumps(v)) elif k.startswith("受入年齢"): if not v: continue assert v in MARU if re.search("満3~",k): v = "満3歳" elif re.search("3\s*[~ー]", k): v = "3歳" elif re.search("4\s*[~ー]", k): v = "4歳" else: raise ValueError(json.dumps(k)) if not g.value(R, NS1["受入年齢"]): g.add((R, NS1["受入年齢"], Literal(v))) elif "預かり保育" in k: if v and v not in DASH: if "実施" in k: S = BNode(obj["施設名"]+"預かり保育") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("預かり保育"))) g.add((S, NS1["回数"], Literal(v))) azukari = S elif "朝の" in k: m = re.match("(\d+:\d{2})~", v) if m: assert azukari g.add((azukari, NS1["朝_開始時刻"], Literal(m.group(1)))) else: raise ValueError(json.dumps(v)) elif "夕方の" in k: m = re.match("~(?P<tm>\d+:\d{2})([\((](?P<note>.*?)[\))])?", v) if m: assert azukari, obj g.add((azukari, NS1["夕_終了時刻"], Literal(m.group("tm")))) if m.group("note"): g.add((azukari, NS1["夕_備考"], Literal(m.group("note")))) else: for s in v.split(): m = re.match("(\d+:\d{2})[~](\d+:\d{2})", s) if m: tm = "%s-%s" % m.groups() g.add((azukari, NS1["夕_終了時刻"], Literal(tm))) else: raise ValueError(json.dumps(v)) else: raise ValueError(k)
def another_try(path): info = {} #IMG_0872 import matplotlib.image as mpimg showimg(to_bin(path)) image = mpimg.imread(path) # img = cv2.imread("/Users/binhna/Downloads/cmnd2.jpg") showimg(image) img = remover(path, 85, 255) img = 255 - img showimg(img) pts = cv2.findNonZero(img) ret = cv2.minAreaRect(pts) (cx, cy), (w, h), ang = ret if w < h: w, h = h, w ang += 90 print(cx, cy, w, h, ang) tmp = img.copy() tmp = cv2.cvtColor(tmp, cv2.COLOR_GRAY2BGR) cv2.rectangle(tmp, (int(cx), int(cy)), (int(cx+w), int(cy+h)), (0, 255, 0), 3) showimg(tmp) M = cv2.getRotationMatrix2D((cx, cy), ang, 1.0) rotated = cv2.warpAffine(img, M, (img.shape[1], img.shape[0])) showimg(rotated) # Resize to height = 1650 x width h, w = rotated.shape[:2] min_edge = 0 if h/w < 1 else 1 factor = 1 if rotated.shape[min_edge] < 1650: factor = 1650/rotated.shape[min_edge] rotated = cv2.resize(rotated, None, fx=factor, fy=factor, interpolation=cv2.INTER_CUBIC) # print(img.shape) showimg(rotated) info['card_number'] = card_number(rotated) print(f"card number: {info['card_number']}") ## (5) find and draw the upper and lower boundary of each lines # [:, rotated.shape[1]//5:int(rotated.shape[1]*2/5)] ## this tmp_img is for getting the lines of text tmp_img = rotated[:, rotated.shape[1]//5:int(rotated.shape[1]*3/5)] tmp_img = denoise(tmp_img) ## horizontal projection hist = cv2.reduce(tmp_img, 1, cv2.REDUCE_AVG).reshape(-1) th = 0 H, W = tmp_img.shape[:2] uppers = [y for y in range(H-1) if hist[y] <= th and hist[y+1] > th] lowers = [y for y in range(H-1) if hist[y] > th and hist[y+1] <= th] print(uppers, lowers) ## make sure uppers and lowers have the same len len_min = min(len(uppers), len(lowers)) uppers = uppers[:len_min] lowers = lowers[:len_min] img = 255 - rotated.copy() rotated = cv2.cvtColor(rotated, cv2.COLOR_GRAY2BGR) for y in uppers: cv2.line(rotated, (0, y), (rotated.shape[1], y), (255, 0, 0), 1) for y in lowers: cv2.line(rotated, (0, y), (rotated.shape[1], y), (0, 255, 0), 1) showimg(rotated) h, w = img.shape[:2] for key, value in hard_code.items(): line = value[-1] if line >= len(uppers): break start = int(value[0]*w) end = int(value[1]*w) sub_img = img[uppers[line]:lowers[line], start:end] sub_img = padding(sub_img) lang = 'jpn_best' if line != 1 else 'eng' result = pytesseract.image_to_string(sub_img, lang=lang) result = unicodedata.normalize("NFKC", result) result = jaconv.normalize(result, 'NFKC') info[key] = result #info['gender'] = '男' if 'M' in info['gender'] else '女' for key, value in info.items(): print(f"{key}: {value}")
def test_normalize(): assert_equal(jaconv.normalize('ティロ・フィナ〜レ', 'NFKC'), 'ティロ・フィナーレ') assert_equal(jaconv.normalize(_concat(HALF_KANA, FULL_DIGIT), 'NFKC'), ''.join(FULL_KANA)+''.join(HALF_DIGIT))
def normalizeStr(str): str = jaconv.normalize(str, 'NFKC') str = jaconv.z2h(str, digit=True, ascii=True, kana=False) str = jaconv.h2z(str, digit=False, ascii=False, kana=True) str = str.upper() return str
def capture(g, page, idx, data, info): try: notes = {p["key"]:p["value"] for p in info if int(p["page"])==page and p["key"].startswith("※")} except: notes = {} slot = None for ri, r in enumerate(data): line = "".join(r) if not line or line[0] in "※*": continue if not "".join(r[1:]): continue if slot is None: slot = r for i,v in enumerate(r): if v: slot[i] = v elif idx[i] in ("所在区","分類","受入開始月齢","卒園年齢"): r[i] = slot[i] obj = dict(zip(idx, r)) R = BNode(obj["施設名"]) skip = [] for i,v in enumerate(r): k = idx[i] if i in skip: continue elif k in ("所在区","施設名","所在地"): m = re.match("(.*)(※[1234567890]*)", v) if m: v = m.group(1) n = notes.get(m.group(2)) if n: g.add((R, NS1[k+"_備考"], Literal(n))) else: raise ValueError(v) if k != "所在地": v = jaconv.normalize(v).replace(" ","") g.add((R, NS1[k], Literal(v))) elif k == "分類": m = re.match("^(?P<institute>.*?)([\((](?P<finance>.*)[\))])?$", v) if m: g.add((R, NS1["分類"], Literal(m.group("institute")))) if m.group("finance"): g.add((R, NS1["財政措置"], Literal(m.group("finance")))) else: raise ValueError(v) elif k == "電話番号": for d in DASH: v = v.replace(d, "-") m = re.match("^(?P<prefix>\d{3}-)?\d{3,4}-\d{4}$", v) if m: if m.group("prefix"): g.add((R, NS1["電話番号"], Literal(v))) else: g.add((R, NS1["電話番号"], Literal("078-"+v))) elif v == "開設予定": g.add((R, NS1["電話番号_備考"], Literal(v))) elif v == "※" and obj["分類"] == "家庭的保育事業": g.add((R, NS1["電話番号_備考"], Literal("相談時にお知らせいたします"))) else: raise ValueError(json.dumps(v)) elif k == "組織": m = re.match("^[\((](?P<le>\w+)[\))]$", v) if m: # legal entity g.add((R, NS1["組織"], Literal(m.group("le")))) else: print(obj, info, page) raise ValueError(k) elif k.startswith("利用定員"): m = re.match("^(?P<num>\d+)(?P<ext>[**])?(\s*[\((](?P<loc>内地域枠\d+)[\))])?$", v) if m: try: int(m.group("num")) except: raise ValueError(json.dumps(v)) g.add((R, NS1["利用定員"], Literal(m.group("num")))) if m.group("ext"): g.add((R, NS1["利用定員_備考"], Literal("別途、1号認定子どもの利用定員を設けています"))) if m.group("loc"): g.add((R, NS1["利用定員_備考"], Literal(m.group("loc")))) else: raise ValueError(v) elif k.startswith("受入開始月齢"): v = jaconv.normalize(v) m = re.match("(生後(\d+[かケヶ]月|\d+日|\d+週目)|\d+歳児クラス|満\d+歳|\d+歳\d+[かケヶ]月)", v) if m: g.add((R, NS1["受入開始月齢"], Literal(v))) else: raise ValueError(json.dumps([k,v])) elif k == "卒園年齢": v = jaconv.normalize(v) m = re.match("※?(\d+歳児クラス)", v) if m: g.add((R, NS1["卒園年齢"], Literal(m.group(1)))) else: raise ValueError(v) if obj["分類"] == "家庭的保育事業": if v in ("0歳児クラス","※2歳児クラス"): g.add((R, NS1["卒園年齢_備考"], Literal("0歳の児童が入所申込み可能です"))) g.add((R, NS1["卒園年齢_備考"], Literal("満1歳到達後は、入所申込みできません"))) if v.startswith("※"): g.add((R, NS1["卒園年齢_備考"], Literal("入所中の児童は、2歳児クラスまで在籍可能です"))) elif v in ("2歳児クラス",): g.add((R, NS1["卒園年齢_備考"], Literal("満3歳未満までの児童が入所申込み可能です"))) elif re.match("^(保育(標準|短)時間|延長保育)", k): v = jaconv.normalize(v) m = re.match("\d+:\d{2}", v) if m: name = re.match("^(保育(標準|短)時間|延長保育)", k).group(0) S = BNode(obj["施設名"]+name) g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal(name))) if "開始" in k: skip.append(i+1) assert "終了" in idx[i+1], idx assert re.match("\d+:\d{2}", r[i+1]) g.add((S, NS1["開始時刻"], Literal(v))) g.add((S, NS1["終了時刻"], Literal(r[i+1]))) else: g.add((S, NS1["終了時刻"], Literal(v))) elif k.startswith("一時預かり"): v = jaconv.normalize(v) if v in MARU: S = BNode(obj["施設名"]+"一時預かり") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("一時預かり"))) else: assert not v, json.dumps(v) elif k == "園庭開放": v = jaconv.normalize(v) if v in MARU: S = BNode(obj["施設名"]+"園庭開放") g.add((R, NS1["service"], S)) g.add((S, NS1["name"], Literal("園庭開放"))) else: assert not v, json.dumps(v) elif k.startswith("終了時間"): pass else: raise ValueError(k)
def apply(self, text: str, form: Form = Form.NFKC): return jaconv.normalize(text, form.name)
def clean(self, data, mecab): normalized = jaconv.normalize(data) for sentence in re.sub(Cleaner.stop_symbol, '\n', normalized).split(): yield self._process_sentence(sentence, mecab)
cv=cv, verbose=2, refit=False) """ 3. Prepare input&output """ ocr_output_src_folder = "/home/vanph/Desktop/pets/lm/official/ocr_logit_data/np_logit_field_7_ffg" mapping_inout = load_data_from_ocr(ocr_output_src_folder) X = [] y = [] for input_fn, lbl in mapping_inout.items(): ctc_logit_matrix = np.load(input_fn) X += [ctc_logit_matrix] y += [jaconv.normalize(lbl)] gs.fit(X, y) print("Best parameters:") print(gs.best_params_) print(gs.best_score_) """ 4. Refit and save model """ from sklearn.externals import joblib lm_model = SklearnAutoCorrectWrapper(**gs.best_params_) lm_model.fit(X, y)
def find_header_start(): for ri, r in enumerate(bulk): cs = [jaconv.normalize(c).replace(" ","") for ci, c in enumerate(r)] if "施設名" in cs: return ri