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

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

ただいまの
回答率

90.49%

  • VB.NET

    916questions

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

  • 正規表現

    798questions

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

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

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 276

SugiuraY

score 182

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

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

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

これに対して

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


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

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

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • think49

    2018/06/30 22:35

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

    キャンセル

  • SugiuraY

    2018/07/01 00:13

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

    キャンセル

  • SugiuraY

    2018/07/01 00:14

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

    キャンセル

回答 5

checkベストアンサー

+4

 旧漢字体

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

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

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

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

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

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

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

function takahashi (string) {
  return /^(?:立候補者の|明日は一緒に行く方は、)(?:.橋太郎|高.太郎|高橋.郎|高橋太.)(?:です!)?$/.test(string);
}

function watanabe (string) {
  return /^(?:立候補者の|明日は一緒に行く方は、)(?:.邉花子|渡.花子|渡邉.子|渡邉花.)(?:です!)?$/.test(string);
}

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

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

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


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

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

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

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


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

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

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

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

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

  • 漢字 (常用漢字表別表第二 に記載されている文字に限る)
  • 平仮名 (ひらがな)
  • 片仮名 (カタカナ)

 日本語の文法

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

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

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

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

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

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

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

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

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

Re: SugiuraY さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/30 22:49

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

    キャンセル

  • 2018/07/01 14:27

    > とお問い合わせすれば、『不可能です』というご回答を頂いて解決していたと思います。
    本音をいえば、私は「不可能です」という回答をしたくはありませんでした。
    厳密には「私の知る限りでは解決手段がありません」が正解であり、他の有識者によって「素晴らしい解決法」が提案される可能性があります。

    また、SugiuraYさんに「不可能です」という回答だけで、納得してもらいたくはありませんでした。
    クリエイティブな作業に携わる者ならば、「不可能」という結論よりも「どういう理屈で不可能なのか」という観点で物事を考えるべきです。
    そうすれば、「あなたは不可能といいましたが、~というアルゴリズムで解決可能なのではありませんか」という反論から、「解決策」が見えてくるかもしれません。

    経験上、結論を急ぐ質問者で最も多い理由は「今回のケースで出来るか出来ないかだけ知りたい。無駄な時間を使いたくない。」です。
    気持ちは理解できますが、その考え方では、今回だけは時間節約できても、次回以降の時間節約は出来ません。
    なぜなら、今回の「なぜ不可能なのか」という理屈の理解が欠けている為、次に同じ理由で不可能な事案が発生しても気が付けないからです。
    従って、同じ理屈で解決可能なはずの問題でも、「可能/不可能」を問う質問を繰り返す事になります。

    では、なぜSugiuraYさんに「不可能です」という回答をしたかといえば、SugiuraYさんの正規表現に対する知識が浅いことが読み取れたからです。
    ですので、私がSugiuraYさんの立場に立ち、私がどう結論するかを決定して、誘導しました。
    早期解決を図った結果ですが、長期的には好ましい方法ではありません。

    親記事に「日本の戸籍法における、人名に使用可能な文字」「日本語の文法」を追記しました。
    私が不可能と結論した理由が書いてあります。
    私は日本語のスペシャリストではない為、この程度が限界ですが、正しく正規表現を使うためには文法理解が不可欠という事は覚えておいてください。
    正しいアプローチは「人名の文法」「日本語の文法」を理解する事です。

    キャンセル

+3

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/30 22:24

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

    キャンセル

  • 2018/06/30 22:31 編集

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

    キャンセル

  • 2018/06/30 22:36

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

    キャンセル

  • 2018/06/30 22:38 編集

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

    キャンセル

+1

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/30 23:58

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

    キャンセル

+1

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


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


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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/30 23:55

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

    キャンセル

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

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • VB.NET

    916questions

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

  • 正規表現

    798questions

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