質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

5回答

1447閲覧

一文字違いで同一文字数で部分一致させる方法

SugiuraY

総合スコア317

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2018/06/30 09:40

編集2018/06/30 13:17

以下のような文字列がございます。

"立候補者の高橋太郎です!"
"明日は一緒に行く方は、渡辺花子"

これに対して、
髙橋太郎// 旧漢字の髙
渡邉花子//旧漢字の邉
は一致するような正規表現を検討しております。

これに対して

pattern ="/.橋太郎|高.太郎|高橋.郎|高橋太./"

では名前の前後の1文字は名前でなくても認識されてしまうため、
立候補者の橋太郎です!
も一致してしまいます。

名前の文字数も含めてその名前の中で1文字だけ異なっても一致するようにさせる正規表現は考えられますでしょうか。

名前かであるのか、名前でないのかという点については、なんらの判断基準を設けることはできません。
前後の文脈があるのかまたはないのかも不明で、前後に特定の文字や空白等があるという規則もありません。
敷いて申し上げれば、例でいえば、
/.橋太郎|高.太郎|高橋.郎|高橋太./
のいずれかに当てはまる特定の文字数の外側にあるものは名前以外であると言うだけです。
したがって、
37歳の高橋太は衆議院議員です。
と言う文字列は"高橋太は"が/高橋太./に一致してしまいます。
質問の趣旨としては
1)これに対応するような正規表現の考え方はありますか?
2)それがない場合には、そもそも不特定の文脈の中にある特定数の文字列でその中の1文字だけが異なるような方法で良い方法が一般的にあるのでしょうか?

と言うことを申し上げたく、上記の2例をあげさせていただきました。
実務的に文脈の中で名前を正規表現で検索する際に、旧漢字等を簡体字で使用されているケースもあるので
1文字だけが間違っている部分一致検索をする場合どのような方法をとっていらっしゃるのかと言うアドバイスをいただきたいと言う趣旨でした。

宜しくお願い申し上げます

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hihijiji

2018/06/30 10:13

そのパターンでイケるはずですが、どんなコードを書きましたか?
YAmaGNZ

2018/06/30 10:14

".藤太郎|佐.太郎|佐藤.郎|.藤太郎"のパターンで"藤太郎"とはマッチしませんでしたが、”佐藤太一郎/藤太郎”とマッチさせたくないということですか?
maisumakun

2018/06/30 10:18

「佐藤太一」にはヒットして「佐藤太一郎」にはヒットさせないということですが、「佐藤太一は、」や「佐藤太一先生」のような文中の名前に対してはどのようにヒットさせればいいでしょうか。
SugiuraY

2018/06/30 10:24

皆様、曖昧な表現で申し訳ございません。追記します
SugiuraY

2018/06/30 10:35

純粋に文に4文字の名前が含まれる、または多くとも1文字の間違いは部分一致としてtrueとしたいと考えていました。
SugiuraY

2018/06/30 10:36

しかしながら、名前の切れ目を前後にで判断することはかなり、困難ですね。。
SugiuraY

2018/06/30 10:37

なので、佐藤太や藤太郎は前後の文脈があるため、諦めざる得ないと思います
think49

2018/06/30 10:47

「名前」と「名前でない文字」をどうやって区別しますか。「立候補者佐藤一です!」なら、「立候補者」と「です!」が名前でないと思いますが、判定基準は何ですか。
YAmaGNZ

2018/06/30 10:52

「立候補者 です!にはパターンがありません。」は前後の文字列がどうなるか不定ということだと思いますので、名前の頭部分と終わり部分の判断は無理なんじゃないですかね?
SugiuraY

2018/06/30 10:56

おっしゃるとおりです。検索対象に含まれる名前以外の部分と名前部分を分ける事は困難な状況です
think49

2018/06/30 11:05

「立候補者佐藤太郎です!」は「立候補者の佐藤太郎です!」か「立候補者は佐藤太郎です!」で意味が変わるわけで、読み手の解釈によって文意が変わる事は往々にしてあります。 名前の識別も同じで、その人が名前と思えば名前で、名前と思わなければ名前ではありません。
think49

2018/06/30 11:05

機械は人間ではないので、書いたようにしか動きません。ですので、あなたが「基準」を作って下さい。現状では「一番いいやつを頼む」並みに要求仕様が曖昧です。
SugiuraY

2018/06/30 12:12

皆さまにコメントを頂くなかで、曖昧であることがわかりました。出来るだけ実際の状況に合わせた質問内容に修正いたしました。
think49

2018/06/30 12:48

結局、「名前でない文字」の定義は何ですか。
SugiuraY

2018/06/30 13:15

コメントありがとうございます。名前でない文字の定義はなく区別不能です。唯一手がかりになるのは、検索対象となる文字数とその文字数の中で1文字だけが違っていても一致と判断したいと言うことをお伝え差し上げたつもりでした。
SugiuraY

2018/06/30 13:16

これをできるだけ詳細に加筆をさせていただきましたが、冗長な言い方となり読みづらくなっていたら申し訳ございません。
SugiuraY

2018/06/30 13:21

もちろん、頻出の"高"、"辺"、"沢"、"斎"などをプログラム上準備しておくと言うてもあるのですが、これをすべてに対応することは困難でもれも怖いので、文章の中で出てくる名前で対象でぶつける名前が仮に1文字相違していても一致とする部分一致として認めるための正規表現上の技術を必死で調べています。
think49

2018/06/30 13:32

はっきりいえば、「名前以外」を回答者に丸投げしている点が問題だと申し上げています。 「名前以外」の定義は不可能なのです。
think49

2018/06/30 13:35

ところで、旧字体への対策として「1文字だけが間違っている部分一致」させるそうですが、「高橋太郎」は「高橋一郎」にマッチします。私は問題だと思いますが…。
SugiuraY

2018/06/30 15:13

あまり、コードに関連がないと判断して、最終的には人の目で確認するという点は言及しませんでしたが、そこはむしろマッチさせて人の目で確認させたいレベルと考えておりました。一方で2文字はさすがにやりすぎと思っておりました。
SugiuraY

2018/06/30 15:14

「名前以外」を回答者に丸投げしている点については、お詫び申し上げます。
guest

回答5

0

ベストアンサー

旧漢字体

髙橋太郎// 旧漢字の髙
渡邉花子//旧漢字の邉
は一致するような正規表現を検討しております。

旧漢字体を文字クラスで指定すればいいでしょう。

JavaScript

1/[高髙]橋太郎/.test('高橋太郎'); 2/[高髙]橋太郎/.test('髙橋太郎'); 3/渡[辺邉]花子/.test('渡辺花子'); 4/渡[辺邉]花子/.test('渡邉花子');

名前の中で1文字だけ異なっても一致

名前の文字数も含めてその名前の中で1文字だけ異なっても一致するようにさせる正規表現は考えられますでしょうか。

何度もいいますが、「名前」と「名前でない文字」を定義しなければ正規表現は作れません。
そして、あなたが想像しているように完全な方法はないので、あなたがあなたの責任において定義しなければなりません。

あえて、いい加減にかくなら、こうです。

JavaScript

1function takahashi (string) { 2 return /^(?:立候補者の|明日は一緒に行く方は、)(?:.橋太郎|高.太郎|高橋.郎|高橋太.)(?:です!)?$/.test(string); 3} 4 5function watanabe (string) { 6 return /^(?:立候補者の|明日は一緒に行く方は、)(?:.邉花子|渡.花子|渡邉.子|渡邉花.)(?:です!)?$/.test(string); 7}

あなたはおそらく、こう思うでしょう。

「でも、. は『名前でない文字』にもマッチしてしまいますよね」

その通りですね。
では、『名前でない文字』とは何でしょうか。
あなたはそれを定義できますか。


そして、あなたはこうも思うでしょう。

「"立候補者の~です!" に限らず、前後の文章が何であってもマッチしてほしいんです。」

はい。そうですね。それが理想ですね。

では、前後の文章が何で合ったらマッチせず、何であったらマッチさせたいですか。
「名前でない文字」ならマッチさせず、「名前の一部」ならマッチさせたいですよね。
では、どんな文字が「名前の一部」として扱われたいですか。


名前でない文字の定義はなく区別不能です。

では、「任意の一文字」の表記揺れ対策としては、誤爆を防ぐ方法はありません。
新旧漢字体のリストを作って対応すべきでしょう。

日本の戸籍法における、人名に使用可能な文字

第六十条 戸籍法第五十条第二項の常用平易な文字は、次に掲げるものとする。
一 常用漢字表(平成二十二年内閣告示第二号)に掲げる漢字(括弧書きが添えられているものについては、括弧の外のものに限る。)
二 別表第二に掲げる漢字
三 片仮名又は平仮名(変体仮名を除く。)

まとめると、次のように。

日本語の文法

正規表現とは、特定の文法に則った文字列から特定の文字列を検索するものです。

「URL文字列」を抽出するなら、URLの文法規則を知っていなければなりません。
「HTMLタグ」を抽出するなら、HTMLの文法規則を知っていなければなりません。
「人名」を抽出するなら、「人名」の文法規則を知っていなければなりません。

では、人名の文法とは何なのか。
ぐぐれば、戸籍法に則っていることが分かります(前節参照)。
日本の人名に使える文字は「漢字」「ひらがな」「カタカナ」の三種ですが、他に規則性を表すものはありません。
姓名が必要な都合上、フルネームで2文字以上という制約はありますが、それだけです。

日本語は英語と違い、単語の区切りを識別しづらい言語です。例えば、次の日本語を考えてみましょう。

「JavaScript愛を感じます」(JavaScriptへの深い愛情を感じます) 「加藤愛を感じます」(加藤さんへの深い愛情を感じます or 加藤愛さんを感じます)

後者は2つの解釈が成り立ちますが、この文章だけでは判断することは出来ません。
前後の文脈から想像するわけですが、それでも100%正しいとはいえません。

また、「漢字だけで構成される人名」に限り、漢字の連続を名前と見なす事は可能ですが、

「加藤様」(加藤 + 様) 「佐藤殿」(佐藤 + 殿)

このように「敬称」が付くと、「名前」と「敬称」を区別することが出来ません。
「様」「殿」は常用漢字表に載っており、名前に使用される可能性がありますので、末尾にそれがあるからといって、除外することは出来ません。
敬称に限らず、名前の前後に関する漢字が来るケースは他にもあるでしょう。
それに対して完璧に名前以外と判断する術を私は持ちません。

Re: SugiuraY さん

投稿2018/06/30 13:22

編集2018/07/01 05:19
think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2018/06/30 13:49

think49様 詳細なコメント及びご回答をいただき誠にありがとうございます。 実はまさに私が知りたいご回答でした。ご質問差し上げる方法がよくなかったととても反省しているのですが、明確にやりたいゴールがあってこれを正規表現によって対応することが可能でしょうか? とお問い合わせすれば、『不可能です』というご回答を頂いて解決していたと思います。 もしあればという趣旨で質問差し上げており、そのような正規表現を作っていただきたいというところはもとより意図しておりませんでした。 あらかじめ、リストを作って対応する方法は検討していたのですが、下記に記した通り、漏れが強かったのですが、明確なご回答をいただきましたので、本格的にそのような方法で検討してみようと思います。 改めて、ご教示いただきましたことを御礼申し上げます。
think49

2018/07/01 05:27

> とお問い合わせすれば、『不可能です』というご回答を頂いて解決していたと思います。 本音をいえば、私は「不可能です」という回答をしたくはありませんでした。 厳密には「私の知る限りでは解決手段がありません」が正解であり、他の有識者によって「素晴らしい解決法」が提案される可能性があります。 また、SugiuraYさんに「不可能です」という回答だけで、納得してもらいたくはありませんでした。 クリエイティブな作業に携わる者ならば、「不可能」という結論よりも「どういう理屈で不可能なのか」という観点で物事を考えるべきです。 そうすれば、「あなたは不可能といいましたが、~というアルゴリズムで解決可能なのではありませんか」という反論から、「解決策」が見えてくるかもしれません。 経験上、結論を急ぐ質問者で最も多い理由は「今回のケースで出来るか出来ないかだけ知りたい。無駄な時間を使いたくない。」です。 気持ちは理解できますが、その考え方では、今回だけは時間節約できても、次回以降の時間節約は出来ません。 なぜなら、今回の「なぜ不可能なのか」という理屈の理解が欠けている為、次に同じ理由で不可能な事案が発生しても気が付けないからです。 従って、同じ理屈で解決可能なはずの問題でも、「可能/不可能」を問う質問を繰り返す事になります。 では、なぜSugiuraYさんに「不可能です」という回答をしたかといえば、SugiuraYさんの正規表現に対する知識が浅いことが読み取れたからです。 ですので、私がSugiuraYさんの立場に立ち、私がどう結論するかを決定して、誘導しました。 早期解決を図った結果ですが、長期的には好ましい方法ではありません。 親記事に「日本の戸籍法における、人名に使用可能な文字」「日本語の文法」を追記しました。 私が不可能と結論した理由が書いてあります。 私は日本語のスペシャリストではない為、この程度が限界ですが、正しく正規表現を使うためには文法理解が不可欠という事は覚えておいてください。 正しいアプローチは「人名の文法」「日本語の文法」を理解する事です。
guest

0

1文字だけが間違っている部分一致検索をする場合どのような方法をとっていらっしゃるのか

表記揺れへの対応であれば、間違いうる文字の対応表を作っておいて、/渡辺//渡[辺邉邊]/のように置き換える、というのが現実解ではないかと思います

投稿2018/06/30 13:16

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2018/06/30 13:24

maisumakun様 コメントありがとうございます。 承知を致しました。どこまでもれずに拾えるのかと言う不安もございますが、現状とっている方法で想定外の一致をしてしまう量ともれてしまい得る量を比較して検討してみようと思います。 実務上の側面からのアドバイスに御礼申し上げます。
SugiuraY

2018/06/30 13:36 編集

申し訳ございません、念のために確認したいのですが、 佐藤太郎という名前は /.藤一|佐.一|佐藤./   //本当は佐藤一の1文字違いを検索したいはずですが// という正規表現 に一致してしまいます。もともと勉強していた他の言語では.は任意の1文字のため一致しないはずなのですが、.NET特有の仕様なのかご存知でしょうか? 重ねてで申し訳ございませんが、よろしくお願い申し上げます。
maisumakun

2018/06/30 13:36

特に指定しない場合は正規表現は部分一致ですので、「佐藤太郎」のうちの「佐藤太」は「佐藤.」でマッチします(.NETに限らず、ほとんどの環境で成立すると思います)。
SugiuraY

2018/06/30 13:39 編集

あ、申し訳ございません。これがいわゆる名前か名前ではないかの基準がないので、少なくとも佐藤太郎には佐藤.が含まれるため、一致ということですね。。。失礼しました。 さすがにこれを最短で一致3文字だけに限定してX.藤一Xのうち Xの部分は無視して最短でというのは、think49様がおっしゃるような名前ではない部分の法則がなければ判断できないですよね。
guest

0

「1文字だけ異なっても」という部分が気になりました。例えば「渡辺龍一郎」さんという方がいらっしゃった場合、「渡邊竜一郎」でもマッチさせたくなるかと思いますが、2文字以上は想定しないで大丈夫でしょうか。


事前にMeCabなどで形態素解析をしておいて、人名と思われる部分を切り出しておくというアプローチもありそうです。


他の方も回答されていますが、やはり適合率(間違ったものをヒットさせない)と再現率(取りこぼさない)の話になるかと思います。

開発されているシステムの要件がわかりませんが、もしヒトの目が入る作業(例えばGoogleのネット検索のように、検索結果の一覧の中から「ヒト」が目的のものを選ぶといった作業)なのであれば、再現率が高い方法と適合率が高い方法を組み合わせるのも手です。

例えばSugiuraYさんが考えられた「1文字違いを拾う」という方法は取りこぼしを減らす方法なので再現率を高めるアプローチになります。一方、文字の対応表を用意する方法は間違いを減らしますので適合率を高くするアプローチです。これらを両方実行して結果をマージすれば、まず取りこぼしが減らせます。また、両方にマッチしたものを結果リストの上位に並べて、片方にしかマッチしなかったものを下位に並べれば、「ヒト」にとっては適合率が上がるため、いいところ取りができる感じです。

投稿2018/06/30 14:32

segavvy

総合スコア958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2018/06/30 14:55

コメントありがとうございます。 なるほど、組み合わせることで、最終的にヒトの目を通す前提と適合率と再現率の両方の側面から情報の序列をつけて最終的に最適解を目指すという考え方ですね。 当初思っていたほど、単純な問題ではなさそうですね。 今回の質問で、アプローチ方法という意味で多くの考え方やアドバイスがいただけて本当に良かったです。 ありがとうございます。
guest

0

名前かであるのか、名前でないのかという点については、なんらの判断基準を設けることはできません。

なら無理でしょうね。
ひらがな混じりの名前はどうしましょう、名前の前後に漢字が来ればどうなる?と考えれば自明のことと思います

現実的には、名前とはどういうものかを定義しないと/できないとどーしようもないです

投稿2018/06/30 13:58

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2018/06/30 14:58

コメントありがとうございます。 もしかしたらという淡い期待だったのですが、検索対象となる文字列数が決まっているのであれば何かうまい方法があるのではと思ったのですが、難しそうですね。 明確なご回答をいただき、誠にありがとうございます。
guest

0

どうしても分けたいというのであれば、言語解析を行う方法はあるかと思います。
MeCabなどの形態素解析を行うライブラリがあります。
ただ、この場合でも完全とは言えませんし、ここまでコストをかけるべきなのかもあります。

旧新字の違いのみを許容するのであれば、他の方も言っている通りリスト化して対応するのがよいと思います。
また、旧新字の違いではなく一字違いを許容するのであれば、「高橋太郎さんと高畑太郎さん」と別人を同一と判断する形になったりしますが、これはよいのかなど問題点もあるかと思います。

投稿2018/06/30 13:49

YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問