日本語のマッチング(正規表現)の解決方法

このQ&Aのポイント
  • 日本語のマッチング(正規表現)を解決するための方法について質問です。
  • 質問者は、xxx.txtの内容を変換するプログラムを作成したが、出力ファイルに何も変化がない問題が発生している。
  • また、5.8.4では通るが、5.8.7ではエラーが起きてしまうという問題もある。どのように解決すればよいか教えてほしい。
回答を見る
  • ベストアンサー

日本語のマッチング(正規表現)

以前解決済みとしたのですが、解決していないので もう一度よろしくお願いします。 以下のプログラムは、xxx.txtの内容を例えば、 (1)ぁ→ァ (2)シイ→シー (3)オウ→オー に変化させようというものです。 現在のところ、出力ファイルには何も変化していない ファイルが出力されるだけです。 use encoding 'euc-jp';は5.8.4では通りますが、 5.8.7ではエラーとなってしまいます。 入力ファイルの文字コードはEUC、改行コードはLF。 このperlファイルも同じ文字、改行コードを用いて います。 どのように書けばよいのか、よろしくお願いいたします。 open(IN, "xxx.txt"); open(OUT, "> ***.txt"); while($b=<IN>){ for($i=0; $i<=258; $i++){ if($b[$i] =~ /[ぁぃぅぇぉ]/){ $b[$i] =~ s/[ぁぃぅぇぉ]/[ァィゥェォ]/; } if($b[$i] =~ /[イシチニ]イ/){ $b[$i] =~ s/イ/ー/; } if($b[$i] =~ /[オクグコゴスズソゾツヅトドヌノフブプホボポムモヤユヨャュョルロ]ウ/){ $b[$i] =~ s/ウ/ー/; } } } close(IN); close(OUT);

  • Perl
  • 回答数5
  • ありがとう数5

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

>use encoding 'euc-jp';は5.8.4では通りますが、 >5.8.7ではエラーとなってしまいます。 私の環境は5.8.4なので、確認できないですが、 5.8.7でも使えると思いますが・・ use encoding "euc-jp"; open(IN, "<:encoding(euc-jp)", "in.txt"); open(OUT, ">:encoding(euc-jp)", "out.txt"); while($b=<IN>){ $b =~ tr/ぁぃぅぇぉ/ァィゥェォ/; $b =~ s/([イシチニ])イ/$1ー/g; $b =~ s/([オクグコゴスズソゾツヅトドヌノフブプホボポムモヤユヨャュョルロ])ウ/$1ー/g; print OUT $b; } close(IN); close(OUT);

Achilles1993
質問者

お礼

名前を見てびっくりしました。 以前回答を頂いたBLUEPIXYさんですね。 本当にありがとうございます。 現状は補足のとおりです…。

Achilles1993
質問者

補足

私の環境だとuse encoding "euc-jp";の行で エラーとなってしまいます。 エディタとして「Perlを始めよう」というもの、 パスはperl.exeのある、binファイルに通してあるのですが…。

その他の回答 (4)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

>化ける行の断片は、 >番+バン+2/0/0 >で+デ+61/0/0 >お待ち+オマチ+17/0/0 >の+ノ+71/0/0 を use encoding 'euc-jp'; open(IN, "<:encoding(euc-jp)", "EUC.txt"); で読み込んでもエラーにはなりませんでした。

Achilles1993
質問者

お礼

出来ました!! ありがとうございました. 元のファイルから違うファイルに移し変えたら出来ました. そんなものですね….大変お世話になりました. 私としては20ポイント以上差し上げたい気持ちです. >BLUEPIXY さんが間違うわけなし 結構有名な方なのですね. 私は質問の数が上回っていますが,BLUEPIXYさんを目指して頑張っていきます.

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>すぐの返答は大変うれしいです. 結局なんの解決にもなってないので申し訳ないです・・ >euc-jp "\xE5" does not map to Unicode at jisyo01_1.pl line 65, <IN> line 39. は、入力ファイルを読み込んで、EUC-JPとして読み込み内部表現であるUnicodeに変換するルールが見つからなかったというようなメッセージです。 通常だったらEUCとして変であるとか 文字コードの領域が全て対応しているとは限らないので、 変換できない文字があるということです。 そういう場合には、入力やコードなどを全てUTF-8で処理するのが常道かと思いますが、 よろしければ試してみたいので、 化ける行の断片を補足していただけませんか? あと、関係ないですが >open(OUT, ">:encoding(euc-jp)","> kekka.txt"); の時には、 >open(OUT, ">:encoding(euc-jp)","kekka.txt"); でいいです。

Achilles1993
質問者

お礼

>結局なんの解決にもなってないので申し訳ないです・・。 なんて優しい方なのでしょう。本当にありがとうございます。(涙) 最後のリダイレクトのアドバイスもありがとうございます。 まだ質問ですが…。よろしくお願いいたします。

Achilles1993
質問者

補足

化ける行の断片は、 (jisyo01.txtの内容) 番+バン+2/0/0 で+デ+61/0/0 お待ち+オマチ+17/0/0 の+ノ+71/0/0 などです。 最終結果は で+デ+61/0/0  [で]  D e のようになります。 #スクリプト open(IN,"phone.txt"); $j = 0; while($a=<IN>){ chomp $a; @list = split(/\+/, "$a"); $kana[$j] = "$list[0]"; $yomi[$j] = "$list[1]"; $j++; } close(IN); use encoding "euc-jp"; open(IN, "<:encoding(euc-jp)","jisyo01.txt"); open(OUT, ">:encoding(euc-jp)","> kekka.txt"); while($b=<IN>){ chomp $b; @list2 = split(/\+/, "$b"); $b =~ tr/ぁぃぅぇぉ/ァィゥェォ/; $b =~ s/([イシチニ])イ/$1ー/g; $b =~ s/([オクグコゴスズソゾツヅトドヌノフブプホボポムモヤユヨャュョルロ])ウ/$1ー/g; for($i=0; $i<=258; $i++){ $list2[1] =~ s/$kana[$i]/$yomi[$i]/g; } print OUT "$b [$list2[0]] $list2[1]\n"; } close(IN); close(OUT); use encoding "euc-jp"; open(IN, "<:encoding(euc-jp)","kekka.txt"); open(OUT, ">:encoding(euc-jp)","> kekka2.txt"); @lines = <IN>; @sortedlines = sort @lines; print "@sortedlines\n"; #print $sortedlines[0]; for($i=1; $i<=@sortedlines; $i++){ if($sortedlines[$i] =~ /\s:\s/){ $sortedlines[$i] =~ s/\s:\s/:/; } if($sortedlines[$i] ne $sortedlines[$i-1]){ print OUT $sortedlines[$i]; } } close(IN); close(OUT); use encoding "euc-jp"; require "jcode.pl"; open(IN, "<:encoding(euc-jp)","kekka2.txt"); open(OUT, ">:encoding(euc-jp)",">> 20k.htkdic"); @str = <IN>; foreach $str(@str){ &jcode::convert(\$str, "euc"); } close(IN); print OUT @str; close(OUT); phone.txtの内容(50音の音が入っている) ナ+n a ニ+n i ヌ+n u ネ+n e ノ+n o ハ+h a ヒ+h i フ+f u ヘ+h e ホ+h o など。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

>Can't locate encoding.pm in @INC >(@INC contains: C:/Perl/lib C:/Perl/site/lib .) は、encoding.pmが無いってことです。 5.8以降のマニュアルには、encodingの記載があるので、 削除されたかインストールがうまくいっていないのでは? もしくは、そもそもバージョンが5.8未満であるとか

Achilles1993
質問者

お礼

BLUEPIXYさん.すぐの返答ありがとうございます. 質問をしても返答が帰ってこない場合を経験しているので, すぐの返答は大変うれしいです. 補足が長くなってしまいましたが,文字が正常に出力されません…. どのようにしたらよいのかわかりましたらよろしくお願いいたします.

Achilles1993
質問者

補足

その可能性が高いかもしれません. インストールをやり直してみます. ところで違う問題が出てきてしまいました. もう一度お願いできますか…. スクリプトを走らせると,エラーメッセージが 出た後,出力ファイルにはかなや漢字が文字化け した結果が出力されています. もちろんuse encoding "euc-jp"はopenする前に に必要なのでしょうが…. よろしくお願いいたします. #変換処理 use encoding "euc-jp"; open(IN, "<:encoding(euc-jp)","jisyo01.txt.cha"); open(OUT, ">:encoding(euc-jp)","> kekka.txt"); while($b=<IN>){ chomp $b; @list2 = split(/\+/, "$b"); $b =~ tr/ぁぃぅぇぉ/ァィゥェォ/; $b =~ s/([イシチニ])イ/$1ー/g; $b =~ s/([オクグコゴスズソゾツヅトドヌノフブプホボポムモヤユヨャュョルロ])ウ/$1ー/g; for($i=0; $i<=258; $i++){ $list2[1] =~ s/$kana[$i]/$yomi[$i]/g; #r駻 囁圦q繒灑*r r゜r r r qハzfqロqヌysuオ } print OUT "$b [$list2[0]] $list2[1]\n"; } close(IN); close(OUT); #ソートと重複要素取り除く use encoding "euc-jp"; open(IN, "<:encoding(euc-jp)","kekka.txt"); open(OUT, ">:encoding(euc-jp)","> kekka2.txt"); @lines = <IN>; @sortedlines = sort @lines; print "@sortedlines\n"; #print $sortedlines[0]; for($i=1; $i<=@sortedlines; $i++){ if($sortedlines[$i] =~ /\s:\s/){ $sortedlines[$i] =~ s/\s:\s/:/; } if($sortedlines[$i] ne $sortedlines[$i-1]){ print OUT $sortedlines[$i]; } } close(IN); close(OUT); #ファイルに出力 require "jcode.pl"; open(IN, "kekka2.txt"); open(OUT, "> 20k.htkdic"); @str = <IN>; foreach $str(@str){ &jcode::convert(\$str, "euc"); } close(IN); print OUT @str; close(OUT); エラーメッセージ euc-jp "\xE5" does not map to Unicode at jisyo01_1.pl line 65, <IN> line 39. euc-jp "\xA1" does not map to Unicode at jisyo01_1.pl line 35, <IN> line 94. このようなものが何行も続く.

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>私の環境だとuse encoding "euc-jp";の行で 5.8.7にアップデートしてみましたが、 #1のスクリプトで問題有りませんでした。 INのファイル及びスクリプトが本当にEUCになってますか? エラーメッセージはどのようにでていますか

Achilles1993
質問者

お礼

すぐの返答ありがとうございます。 またの質問になりますがよろしくお願いいたします。

Achilles1993
質問者

補足

INファイル及びスクリプトはEUCになっています。 エラーメッセージは、 Can't locate encoding.pm in @INC (@INC contains: C:/Perl/lib C:/Perl/site/lib .) at jisyo01_1.pl line 14. となっています。

関連するQ&A

  • 日本語のマッチング(正規表現)

    Perl5.8.7で日本語のマッチングを行おうとしてます. 文字コードはEUCで,[ト],[ユ],[ャ],[ュ]や[ョ] の後にある[ウ]を[ー(長音)]に変換しようとする ものです. 例.ヒャクトウバン→ヒャクトーバン 自分の考えた正規表現では成功しませんでした. if($b[$i] =~ /[\xa5e6\xa5c9\xa5e3        \xa5e5\xa5e7]\xa5a6/){ $b[$i] =~ s/\xa5a6/\xa1bd/; } 文字コードを直接書く方法しかないのか, 日本語はマッチングできるのかなどわからないので, よろしくお願いいたします.

    • ベストアンサー
    • Perl
  • 正規表現について2

    すみません、前回「正規表現について」でお世話になりました者です。 前回の分は解決したのですが、それに関連してもう少し教えてください。 data.txt---------------------------------------- aaabbbccc aaadddccc aaaeeeccc ------------------------------------------------ test.pl----------------------------------------- #!C:\Perl\bin\perl use CGI; my $q = CGI->new; $q->charset('Shift_JIS'); print $q->header(-type => "text/html"); my $line=0; open(IN,"<data.txt"); open(OUT,">output.txt"); while(<IN>){ if ($line++==0){ $output1="$1" if/aaa(.*?)ccc/;} s/aaa(.*)ccc/$1/ if (?aaa(.*)ccc?); print OUT; } close(OUT); close(IN); print $output1; ------------------------------------------------ とすることで、得られたい結果である、 output.txt-------------------------------------- bbb aaadddccc aaaeeeccc ------------------------------------------------ IEでの表示-------------------------------------- bbb ------------------------------------------------ となりました。そこで今回教えていただきたいのは、 data.txt---------------------------------------- <空行> aaabbbccc aaadddccc aaaeeeccc ------------------------------------------------ というようにdata.txtのはじめが空行の場合にも、 上記と同じような結果を得たいです。output.txtの はじめは空行になっても構いません。得られる文字として、上と同じ結果がほしいです。どうしたらよいでしょうか?よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perlを使った正規表現について

    テキストファイルを読み込んで、以下のルールに従った文字列だけを.txtで出力するプログラムを書いています。 具体的にはテキストファイル中の "text":"★★★","to_user" で囲まれている★★★の部分のみを抽出したいです。 そこで正規表現に触りだしたのですが、表現がうまくいっていないようで1週間ほどはまっています。。うまく出力できるように直しをいただけないでしょうか。 打ち明けてしまうと、★★★の部分はtwitterの呟き(日本語)になります。 以下がそのソースになります。よろしくお願いします。 print "Input file name: "; $ifname = <STDIN>; open(IN, $ifname); open(OUT, "> out.txt"); #出力ファイル while(<IN>){ if($ifname =" m/"test":(.*?),"to_user"/; next if($_ eq ""); print OUT "$_\n"; #書き出し } close(OUT); close(IN);

    • ベストアンサー
    • Perl
  • 配列を用いた文字置換

    初投稿です。よろしくお願いいたします。 kana2phone_rule.txtにはア+aという情報が五十音で入っています。01.txt.chaには愛+アイという情報が入っています。 以下のプログラムは01.txt.chaのプラスの後の要素 (アイ)を音表記(ai)に変換するというものです。 しかし変換の作業が行われない(アイ)ままファイルを吐き出してしまいます。 文字コードはEUC、改行コードLFで試しても、Jperlを用いてShift-JIS、CR+LFで試してもだめでした。 どこに問題があるのでしょうか。 分かりましたらよろしくお願いいたします。 open(IN,"kana2phone_rule.txt"); $j = 0; while($b=<IN>){ chomp $b; @list = split(/\+/, "$b"); $kana[$j] = "$list[0]"; $yomi[$j] = "$list[1]"; $j++; } close(IN); open(IN, "01.txt.cha"); open(OUT, "> kekka.txt"); while($a=<IN>){ chomp $a; @list2 = split(/\+/, "$a"); for($i=0; $i<=258; $i++){ $list2[1] = ~s/$kana[$i]/$yomi[$i]/g; } print OUT "$a [$list2[0]] $list2[1]\n"; } close(IN); close(OUT);

    • ベストアンサー
    • Perl
  • ファイル読み込みマッチングについて

    現在二つのファイルをつき合わせて一致しない ファイルを出力するようなものを作っています。 例ですが。 ---a.txtココカラ--- aaa bbb ccc ---ココマデ--- ---b.txtココカラ--- aaa ccc ddd fff ---ココマデ--- 上記ファイルを照らし合わせて 以下のファイルを出力 ---c.txtココカラ--- bbb ---ココマデ--- のように出力させたいのですが。 自分の作成したものは ---a.plココカラ--- open(IN1,"a.txt") || die $!; open(IN2,"b.txt") || die $!; open(OUT,">c.txt") || die $!; sub hikaku { while(<IN2>){ if($a eq $b){ return; } } print OUT "$a"; return; } while(<IN1>){ $a = $_; &hikaku; } close(IN1); close(IN2); close(OUT); ---ココマデ--- いろいろテストをしてわかったことですが サブルーチンの while(<IN2>) そのままに なる一回しか回らないことがわかりました。 これは偽になった後、サブルーチンを抜けまた 回ってきた時に偽と判断されるからでしょうか? プログミング自体始めたばかりなので、こんなん あかんに決まってるやん!とか一からだなこれ!! とか導いていただけるなら厳しいご指摘お待ちして おります。 長くなりましたがよろしくお願い致します!!

    • ベストアンサー
    • Perl
  • いずれかのパターンにマッチング

    はじめまして、初歩的な質問ですがご教授いただければ幸いです。 英文(1文ずつ改行されたもの)から" to "または"by "または" with "を含む文のみを表示する構想のスクリプトを作りましたが、それ以外の関係ない文も出力されてしまいます。 elsif~endまでを取り除くと、to(大文字小文字の区別なし)を含む文のみ出力してくれるのでおそらく悪いのはelsifの所だとは思うのですがなぜこれではだめなのかわかりません。 ほんとに馬鹿な質問ですが教えていただければありがたいです。よろしくお願いします。 a = Array.new   filename = ARGV[0]  file = open(filename) while b = file.gets do    b.chomp!     if b =~ /\s+to\s+/i then      a << b    elsif b =~ /by\s+/i     a << b    else b =~ /\s+with\s+/i     a << b    end end for c in a  puts c end file.close

    • ベストアンサー
    • Ruby
  • 正規表現<置き換え>が実行してくれません

    次のようなスクリプトで、改行マーク\nがたくさんある1行データを<BR>に置換しようとしましたが、表示は\nのままです。原因が分かりません。たぶんこの肝心の箇所のスクリプト・エラーだと思いますが、自分で発見できません。どなたかお教え下さい。 print "Content-type: text/html; charset=sjis-jp\n\n"; print "\n"; print "<HTML>\n"; print "<HEAD>\n"; print "<TITLE></TITLE>\n"; print "</HEAD>\n"; print "<BODY>\n"; # 辞書を読む #ファイルの各行を配列に一括して読み込む。 open(IN, "GermJ.txt"); @list = <IN>; close(IN); $max = $#list; for ($i=0; $i<$max; $i++) {$data = @list[$i]; if (index($data, $tango.' /// ')==0) {$data=~ s/ \n/<BR>/g; print "$data\n"; last; } } print "</BODY>\n"; print "</HTML>\n"; __END__

    • ベストアンサー
    • Perl
  • 正規表現での置き換え

    正規表現で取り込んだテキストファイルの置き換えをしようとしています。 テキストファイルには Vol:down1b (Vol:down1b (F:\download1\sampledata))\sample.jpg Vol:down1b (Vol:down1b (F:\download1\sampledata))\sample2.jpg と入ってます。 Perlのプログラムでは $moto = "Vol:down1b (Vol:down1b (F:\download1";#1の置き換え元 $ato = "down1";#1の置き換え後 $moto = quotemeta($moto); open(IN,"list.txt") || die "ファイルが見つからないので終了します。"; @file=<IN>; for(@file){ $_=~s/$moto/$ato/; } close(IN); print"@file[10]","\n"; と書きましたが、なぜか置き換えがうまくいきません。 $moto変数の中にある(とかの文字があるのがだめなのでしょうか? quotemeta関数でエスケープはつけてるつもりですが・・・ 教えてください。よろしくお願いいたします。

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

    検索システムを作ろうと思っています。テキストファイル(このソースではgreetings.txtです。)の中にある文章をキーボード入力で1文字でもヒットすれば抜き取って表示させたいのですが、以下のソースをコマンドプロンプトで実験したところ「Q、Y,S,M、と記号」で検索すると全ての文章がヒットしてしまいます。他の文字では問題無くヒットするのですが…。perlを始めてばかりでまだまだわからないことだらけです。いちおう本やネットで検索したんですがさっぱりわかりません。どなたかどうかお力を貸していただけませんか? #!C:\Perl\bin\perl $kensaku = <>; $ans = eval $kensaku; open(IN, "greetings.txt"); while ($line = <IN>){ if($line =~ /$ans/i){ print "$line"; } }

    • ベストアンサー
    • Perl
  • 正規表現で  " ← を削除するには?

    " がある文があって、これを削除したいのですが、 $file="KEN_ALL.csv"; open (IN, $file) or die "$!"; while (<IN>) { $_ =~ s/\"//; print $_; print "<br>"; } close (IN); と書いたのですが、削除できませんでした。「"」はどうやって削除できるんでしょうか?やりたいことは、CSVファイルの各セルの中に「"」がたくさんあって、それを一気に削除したいのです。

    • ベストアンサー
    • Perl