アプリ版:「スタンプのみでお礼する」機能のリリースについて

英語と日本語が交ざっているテキストから日本語部分を抽出するプログラムをPerlで書きたいと思って以下のようなプログラムを組みました。


---
#!/usr/bin/perl

print "Input file name: ";
$ifname = <STDIN>;

#print "Output file name: ";
#$ofname = <STDIN>;
$ofname = ">> tmp.txt";

open(INPUTFILE, $ifname);
open(OUTPUTFILE, $ofname);

while($c = getc(INPUTFILE)){
if('a'<= $c && $c <= 'z' ||
'A'<= $c && $c <= 'Z'){
}else{
print OUTPUTFILE $c;
}
}

close(INPUTFILE);
close(OUTPUTFILE);
---

これを実行したところ、日本語も英語も書き出されず、数字だけ書き出されてしまいました。

日本語部分だけを抽出するようにするにはどのようにすれば良いでしょうか。
ご教示願います。

A 回答 (6件)

open(IN, "< euc.txt"); #対象ファイル


open(OUT, "> euc.out.txt"); #出力ファイル
while(<IN>){
tr/\x0D\x0A//d; #改行を一旦削る
tr/[\x00-\x7F]//d; #1バイト文字除去
next if($_ eq ""); #空らな次の行へ
print OUT "$_\n"; #書き出し
}
close(OUT);
close(IN);

1バイト文字を全て消し去ることで2バイト文字が残るという方法です。(注:ファイルはEUCであることが前提。ShiftJISの場合は[\x00-\x7F\xA1-\xDF]になります。)
    • good
    • 0

補足です。


書き忘れましたがNo.5の方法だと半角カナは残ります。
半角カナも除去したいのなら
s/\x8E[\xA1-\xDF]//g;
を追加してください。
(tr/\x8E[\xA1-\xDF]//d;だと文字化けします)
    • good
    • 0
この回答へのお礼

Etherskyさん、具体的にプログラムを書いていただいてありがとうございます。

おかげで基本的な部分はできてきたと思います。
フィードバックとして現在のコードを乗せておきます。
処理についてはEtherskyさんにご教示いただいた方法です。
それ以外にフォルダ内のファイル(.c, .h)を開き、それぞれのファイル名に.outを付け足して出力ファイルとする方法をとりました。
---

#!/usr/bin/perl

#ディレクトリのオープン
opendir (DIR,"./") ;
@files = grep { /\.c$/ || /\.h$/ } readdir DIR;
#@files = grep { /\.c$/} readdir DIR;
close DIR;
print "1" ;
foreach $ifname (@files){
print "2" ;
$ofname = "> ".$ifname.".out";

open(IN, $ifname ); #対象ファイル
open(OUT, $ofname ); #出力ファイル

while(<IN>){
tr/\x0D\x0A//d; #改行を一旦削る
tr/[\x00-\x7F]//d; #1バイト文字除去
next if($_ eq ""); #空らな次の行へ
print OUT "$_\n"; #書き出し
}
close(OUT);
close(IN);
}

---

ありがとうございました。

お礼日時:2004/11/02 11:56

EUCならShift-JISより簡単かな?


半角カナとかが無いなら

while ・・・
{
  if ($c >= \x80) {
      #0x80以上はEUCの漢字コードとみなす
      print OUTPUTFILE $c;
  }
}

で、いかがでしょう?
本当は1行ずつ読んで正規表現使って処理するのが良いのですが。
(Ethersky様ご紹介のURLが参考になるかと。)

ちなみにこのプログラムだと漢字コードは出力しますが改行とかスペースとかは一切出力されませんのであしからず。
    • good
    • 0
この回答へのお礼

spinach-chickenさん

ありがとうございます。

今回はEtherskyさんの方法で処理することにします。
当初は1文字づつ判定と思ってたのですが、今回の目的には不適と思い至ったので。

Perl暦がまだ浅いのでそこら辺の判断もうまくできませんでした。失礼。m(_ _)m

お礼日時:2004/11/02 11:59

一番簡単なShift-JISのみ抽出するプログラムは以下のようなかんじでしょうか(適当ですが。

getcをしているwhileの前後だけです。)


#------------------------
#漢字かどうかのフラグ。
$flg = 0;

while ・・・
{
  if ($flg == 1) {
    #漢字の2バイト目なのでそのまま出力
    print OUTPUTFILE $c;
    $flg = 0;
  } else {
    if ($c >= \x80) {
      #0x80以上はShift-JISで全角文字の1バイト目とみなす
      $flg = 1;
      print OUTPUTFILE $c;
    } else {
      #漢字2バイト目以外の0x80以下の文字は英字とみなす。
    }
  }
}
    • good
    • 0

if('a'<= $c && $c <= 'z' ||


'A'<= $c && $c <= 'Z'){
なによりまず、これだと、
「aより大きくかつzより大きい」または「Aより大きくかつZより大きい」
ということで範囲がおかしいかと。

それから日本語は2バイトで表現されますが、文字コードがShiftJISの場合、漢字の文字コード中に、英語の文字コードが含まれるケースがあります。
(例:「イ」の文字コードは0x8343ですが、2バイト目の0x43は英字の「C」の文字コードです。
このプログラムを作る際は、

(1)日本語と英語を分離するファイルは、何の文字コード(Windowsなら普通Shift-JIS)で書かれているか。

(2)分離する英字はどの範囲か(半角全て(数字や記号を含む)か、アルファベット(A-Z)のみか)

という情報が必要です。
そのあたりはいかがでしょうか?

この回答への補足

>spinach-chickenさn

ありがとうございます。

(1)文字コードはEUC
(2)悩ましいところですが、とりあえず半角すべてを分離しようと思ってます。

つまり、
「EUCで記述されたテキストから日本語(=全角部分)を抽出して別ファイルへ書き込む」
ということを考えてます。

よろしくお願いいたします。

補足日時:2004/11/01 13:23
    • good
    • 0

そのテキスト中の日本語の文字コードは何でしょうか?


それさえ分かっていれば正規表現で抜き出せます。

以下を参照してください。
http://www.din.or.jp/~ohzaki/perl.htm#Character

参考URL:http://www.din.or.jp/~ohzaki/perl.htm#Character
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!