• ベストアンサー

Perlによる自動処理について

前回の質問ではお世話になりました。 おかげで上手く動作させることが出来ました、ありがとうございます。 今回は自動処理について質問したいと思います。 ハッシュに入っている複数の文字列 (あい、あいう、あいうえ、あいうえお) を”あい”としてまとめ、カウントしたいです。 アルゴリズムとしては、前文”あい”が共通しているので、”あい”を含むものを検索してカウントすれば出来ると思うのですが、正規表現など開発の際に単語を指定せずに出来るものなのでしょうか? 少々伝わりにくいと思うので以下に要点をまとめます。 (1)ハッシュに入っている類似文字列について、ひとまとめにカウントしたい。 (2)その際、開発の段階で文字列を指定しない(正規表現のようにパターンを設けない)で、(1)の処理が出来るかどうか。 どのような形でも良いので、複数ある単語をひとつにまとめ、尚且つキーワードを設けないようなものと言われたので、私としても(2)をどうして良いのか分かりません。 実現可能か不可能かだけでも、ご意見頂ければ嬉しいです。 宜しくお願い致します。

noname#97332
noname#97332
  • Perl
  • 回答数7
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.7

>外部ファイルの使用については大丈夫だと思います. >そこで,外部ファイルというのは具体的にどのようなファイルでしょうか? 複数の単語を1つにまとめるための情報を定義したものです。(辞書ファイルのようなものと考えて下さい) 記述の方法は、これから自分で決めることになります。1つの例として、(これが実用に耐えることを意味しませんが)以下のような記述があげられます。三毛猫、ドラ猫のように最後の1文字が猫であるものを、1つのグループにししたい場合、*猫のように定義します。 ここで、*とは何でも良い文字(ワイルドカード)という意味です。 従って、 *猫 *犬 とすれは、最後が猫、犬で終わるものに関する定義をおこなったことになります。尚、*はひとつの例で、この文字をかならず使う必要はありません。また、この場合、野良猫と海猫も*猫にマッチしますが、海猫は除きたいと言う場合は、そのような情報も必要になります。

noname#97332
質問者

お礼

回答ありがとうございます. なるほどー,某多人数チャットのような定義付をすればいいんですね! とても助かります. ありがとうございましたー.

その他の回答 (6)

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.6

ははは。 「黒豚と河豚は似てない。」 「野良猫と海猫は似てない。」 が要求事項なら、 「シェパードとダックスフンドは似てる」も必要ですね。 実現のためには単語辞書が必要です。 仮に目的にかなった単語辞書が入手できたとして、それを使うためには単語分解も必要かも知れません。 エキスパート・プログラマでも、ちょっと手間のかかる仕事になるでしょう。

noname#97332
質問者

補足

度々回答ありがとうございます. Perl自体で自動処理するにしても,別のところで様々な定義付しなくてはならないんですね. そうすると自動化自体にメリットが殆どなくなってしまいますよね. 時間がかかるとしたら,やっぱり要求者にそれを分かっていただいたほうが無難かもしれませんね. ありがとうございます.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

確かに, 「何らかの知識」を与えないと無理ですね>#4. 「ドラ猫、野良猫、海猫」とか「黒豚, 河豚, 海豚」を「似ている」としていいかどうかってかなり微妙だし. 最悪「知識を外部ファイルとして与えて require」とかいう大技に発展するかもしれん.

noname#97332
質問者

補足

回答ありがとうございます. 文字列を羅列するにも,正規表現などで単語をひっかけるにも何らかの言葉は必要ですよね. 外部ファイルを使うこと自体については,形式的な意味で問題ないと思われます. この場合結構な時間が必要とされますよねー….

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

>どのような形でも良いので、複数ある単語をひとつにまとめ、尚且つキーワードを設けないようなものと言われたので、私としても(2)をどうして良いのか分かりません。 「複数ある単語をひとつにまとめ、尚且つキーワードを設けないようなもの」 この部分をハードコーディング(プログラムで直接記述すること)でなく、外部ファイルに定義してよいならばできるかも知れません。それでよいか、質問者様に要求を出した人に、確認されてみてはいかがでしょうか。とにかく、単語をまとめるための情報なしに、プログラムで処理をするのはできないと思いますよ。 (ドラ猫、野良猫、海猫も同じ猫にまとめて良いかどうかは人間しか判断できないと思います)

noname#97332
質問者

補足

回答ありがとうございます. >外部ファイルに定義してよいならばできるかも知れません。 外部ファイルの使用については大丈夫だと思います. そこで,外部ファイルというのは具体的にどのようなファイルでしょうか? 度々お手数おかけします. 宜しくお願いします.

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.3

人間が自然と感じるグループ分けを何の基準も与えずに Perl に全自動でやらせたいのなら、まず不可能でしょう。 > 例として%zooの中に犬、柴犬、警察犬、猫、野良猫、ドラ猫があるとします。 これを「犬」と「猫」に振り分けるなら、以下のいずれかの規則が必要です。 1 末尾 1文字をグループ分け基準にする。 2 「犬」と「猫」をあらかじめ「グループ候補」として登録しておく。 実際、(柴犬、警察犬、警察官) は、どの様にグループ化しますか? 結論では無く根拠・判断基準を教えてください。 ソフトウェア作りをする場合、起こり得る可能性を全て事前に把握して対応を決めておかにゃなりません。 それが不充分な時、バグという名の汚点が生まれます。

noname#97332
質問者

補足

回答ありがとうございます. やはりある程度のキーワードを設けなければ実現は不可能ですね. >1 末尾 1文字をグループ分け基準にする。 については,文字列の一番最後が合致していれば同じグループとして見なすということでしょうか?

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.2

> 前文”あい”が共通しているので 先頭 2文字が一致するものをまとめるなら、先頭 2文字をキーにしたハッシュを作れば良いです。 その方向で、OKですか? NGなら、どういう規則でまとめたいかを詳しく書いてください。 例示された (あい、あいう、あいうえ、あいうえお)のまとめ方が以下でなぜ悪いのかが判らないと何とも答え様がありません。 1 「あ」組のみ 2 「あい」組 + 「あいう」組

noname#97332
質問者

補足

回答ありがとうございます。 ハッシュの中には1万件ほどの単語が入っております。 「キーやパターンを設けて処理するのは大変なので自動でそれらを処理できないか」との話で、どのような形式で処理を行うのか迷っているところです。 例として%zooの中に犬、柴犬、警察犬、猫、野良猫、ドラ猫があるとします。 これを犬はひとまとめに犬、猫はひとまとめに猫としたいです。 犬 3件 猫 3件 このような処理を自動で行うことは可能でしょうか。 何故自動かというと、前述にもあるとおり、本来のハッシュの中身には1万ほどの単語が入っているからです。 説明不足にも関わらず、レスポンスしていただき感謝します。 また不明な点ございましたら、随時対応致します。 宜しくお願いします。

回答No.1

ちょっとよくわからないですが、 --- 「あい」 は 4 回出ました 「あいう」 は 3 回出ました 「あいうえ」 は 2 回出ました 「あいうえお」 は 1 回出ました --- という感じで出力するということでしょうか?以下のようすればできると 思います。use utf8を使用しているのでutf8で保存して下さい。encode( 'utf8'...は環境に合わせて下さい。 --- #!/usr/bin/perl use warnings; use strict; use utf8; use Encode; my %word_of = ( 'あい' => 0, 'あいう' => 0, 'あいうえ' => 0, 'あいうえお' => 0, 'かき' => 0, 'かきく' => 0, 'かきくけ' => 0, 'かきくけこ' => 0, ); foreach my $search_key ( keys %word_of ) { foreach my $word ( keys %word_of ) { if ( $word =~ /$search_key/ ) { $word_of{$search_key}++; } } } foreach my $key ( sort ( keys %word_of ) ) { # utf8, shiftjis eucjp ... print encode( 'utf8', "「$key」 は $word_of{$key} 回出ました" ), "\n"; }

noname#97332
質問者

補足

回答ありがとうございます。 説明不足ですみません。ハッシュを変えて説明しなおします。 %zooの中に犬、柴犬、警察犬、猫、野良猫、ドラ猫があるとします。 これらを犬は犬として3カウント、猫は猫として3カウントしたいです。 犬 3件 猫 3件 このような処理を、"犬"や"猫"という単語を指定しないで行うことは可能でしょうか。 コードまで提供していただいて、本当に申し訳アリマセン。 別のところで教えていただいたコードは活用させていただきます。 ありがとうございました。 また説明不足でしたら随時対応致します。

関連するQ&A

  • php 正規表現で(ただし○○は除く)という処理をしたい

    正規表現を使って複数条件を指定する場合 "文字列内に●がはいっていたらtrue  もしくは、先頭に▲がある場合はfalse" という、論理和的な条件は分かるのですが、 "文字列内に●がはいっていたらtrue  ただし先頭に▲がある場合はfalse" という、論理積的な条件の作り方がよく分かりません。 前者では、「もしくは」になってしまうので 先頭に▲があろうがなかろうが、●さえ入っていればtrueになってしまいます。 しかし、やりたいのは「ただし」であり ●がたとえ入っていようと、▲が先頭にあればflaseにしたいのです。 どうすれば、後者の条件を正規表現で実現できるでしょうか?

    • ベストアンサー
    • PHP
  • Perlによる文字の抽出方法

    プログラム初心者なので、あまりうまく説明できませんが、よろしくお願いします。 あるテキストデータから、一部分だけをだけを取り出したいのです。 例えば、 例1  ■見出し1■   ・データ1   ・データ1  ■見出し2■   ・データ2   ・データ2  ■見出し3■   ・データ3   ・データ3 のようなデータから、■見出し2■とその中にある内容(・データ2の内容は いくつもあるものとする)でだけを取り出したいのですが、どうすれば よいのでしょうか?■見出し*■をkeyとしてハッシュに入れて、複数個 の値をつればようのでしょうか? それとも、他の方法で処理したほうがよいのでしょうか? 文字列から文字列までの指定というのは、どうすればよいのでしょうか? 回答よろしくお願いします。

    • ベストアンサー
    • Perl
  • VB2005での正規表現

     文字列から特定の条件をみたす単語を探す処理をしたいのですが。正規表現という言葉まではたどり着きましたが。まだ初めて間もないため私のレベルでは使い方がわかりません。すいませんが教えてもらえないでしょうか? 開発環境:Visual Basic 2005 Express Edition 例。PRINTERNAMEから始まりPORTNAMEまでの中の文字列を拾いたいのですが。PRINTERNAME**PORTNAME の**部分の文字列を抜き出したいのです。 すいませんがよろしくお願いいたします。

  • perlでの入れ子文字列削除

    perlを利用して文字列処理を行う際に、入れ子になった文字列を削除したいのですが、正規表現のうまいやり方が思い浮かびません。 例としましては 今日は雨(雪ではない(この辺の処理に困っている))が降っている。 という文章を 今日は雨が降っている。 と処理できるようにしたいです。 $data =~ s/(.*?)//g; $data =~ s/)//g; というやり方では、3重以上になった時の処理ができません。 できれば何重になっても可能な方法をご教示ください。

    • ベストアンサー
    • Perl
  • Perl 正規表現に関して

    現在Perlにて正規表現を用い,アクセス者のログが納めてあるlog.datからデータを検索し集計するといったアルゴリズムです. ところが正規表現を用いたのは良いものの,アルファベット以外をパターンとして使用したとき,データを呼び出すどころか表示されない状況に陥ってしまいました. elsif($referer =~ /abcd/i) { $word2 = "abcd"; } 上記のコードは,パターンがアルファベットで構成されているため,正常にシステムが動作します. elsif($referer =~ /あいうえ/i) { $word2 = "あいうえ"; } しかし,上記のコードはパターンが平仮名で構成されているため,冒頭で記している問題が発生してしまいます. そこで (1)パターンにアルファベット以外のものは使えるのか. (2)パターンにアルファベット以外のものを使いたいときはどうすればいいのか. についてお教えください. また正規表現のほかに,文字列を検索し,頻度をカウントすることに長けているコードがございましたらお教え願います. 以上の内容で不明な点等ございましたら随時対応致します. 宜しくお願いします.

    • ベストアンサー
    • Perl
  • Perlの正規表現

    Perlの正規表現である文字列に文字列STRINGが含まれないようにするには ^(?!.*STRING).+$ と書くとググったら出てきました. ですが,?!について詳しいことまで書いてるサイトはありませんでした. ?!は具体的にはどのようなことをするのでしょうか?

  • xxxxxxx = "aaa bbb ccc"という文字列の""で囲まれた部分を処理したい

    最終的にリストにしたいので、正規表現で""内を取り出した後に split /( | )/のような処理をすればいいのだと思うのですが、まず第一に""内の文字列を取り出せません。 はじめのxxxxxxxは決まった文字列ですので、これを変数にできれば早いんですがそういう処理はできないですよね? フォーマットは決まっているのですが、どうやって""内の文字列を取り出せばいいのでしょうか? @ARGV =~ s/\".*\"$/$1/; こういう処理ではうまくいきませんでした。 Perlを触るのが初めてなので、ネットで調べていますがさっぱりわからなくて途方に暮れています。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 0P PHP 正規表現 perlとの違い

    php(PHP5)の正規表現に関する演算子についての質問です。 一つ目の質問 ある特定の1文字が指定した文字列の中に含まれるかどうか調べたいのですが、perlでは「m/a/」のような演算子を使っていました。ですが、PHPでは「m/a/」は使えないようです。PHPでは、どのように記述すればよいのでしょうか? 例 $string = "abcdefg" とし、$stringに「d」が含まれるかどうか調べたい。 ちなみに「stristr」を使用してstristr($string, "d")などとすると, 「d」が$stringに含まれない場合、falseを返してくれるのは良いのですが、含まれる場合、trueではなく文字列の中から一致した検索文字以降を返すのでだめでした(私がどうやるか知らないだけかも)。 2たつ目の質問 また、ある特定の文字の前と後に不特定の一文字又は複数の文字が含まれるかどうか調べたいのですが、以下のような正規表現では、だめでした。 $string ereg(".+@.+",$string) 上記の正規表現の場合、$stringの文字列が「@」一文字だけで「@」の前と後に何の文字もなくてもtrueを返してしまいます(本当は@マークの前後に最低1文字以上の文字列がなければだめなようにしたいのです。)。 どのようにすれば、良いのでしょう? ご存知の方がおられましたら、お教え下さい。 キャサリン

    • ベストアンサー
    • PHP
  • 正規表現で特定の文字列に一致しない条件の指定

    正規表現で特定の文字列(2文字以上)に一致しない場合の条件指定は可能でしょうか? 例えば、[^CEG] と指定すると文字の「C」、「E」、「G」以外の文字にマッチするということになりますが、 複数の文字で構成された文字列で同じようなことをする方法はないのでしょうか? 例えば、「Japan」を含まないなどの指定方法を知りたいです。 以下の場合、文字列の途中に含まれている「Japan」を上手く見つけることができ、 1を除外し2と3だけがマッチする正規表現の指定方法が知りたいです。 1. 「この国はJapanです。」 2. 「この国はChinaです。」 3. 「この国はUSAです。」

  • アルゴリズムの問題教えてください。

    アルゴリズムの勉強をしています。 とりあえず2分探索、ソート各種、 リスト、ハッシュ、2分木AVL木は実装できました。 ほかに定番のアルゴリズムってありますか。 (正規表現は難しすぎて挫折しました。)

専門家に質問してみよう