英語と日本語が交ざっているテキストから日本語部分を抽出するプログラムを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);
---
これを実行したところ、日本語も英語も書き出されず、数字だけ書き出されてしまいました。
日本語部分だけを抽出するようにするにはどのようにすれば良いでしょうか。
ご教示願います。
No.5ベストアンサー
- 回答日時:
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]になります。)
No.6
- 回答日時:
補足です。
書き忘れましたがNo.5の方法だと半角カナは残ります。
半角カナも除去したいのなら
s/\x8E[\xA1-\xDF]//g;
を追加してください。
(tr/\x8E[\xA1-\xDF]//d;だと文字化けします)
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);
}
---
ありがとうございました。
No.4
- 回答日時:
EUCならShift-JISより簡単かな?
半角カナとかが無いなら
while ・・・
{
if ($c >= \x80) {
#0x80以上はEUCの漢字コードとみなす
print OUTPUTFILE $c;
}
}
で、いかがでしょう?
本当は1行ずつ読んで正規表現使って処理するのが良いのですが。
(Ethersky様ご紹介のURLが参考になるかと。)
ちなみにこのプログラムだと漢字コードは出力しますが改行とかスペースとかは一切出力されませんのであしからず。
spinach-chickenさん
ありがとうございます。
今回はEtherskyさんの方法で処理することにします。
当初は1文字づつ判定と思ってたのですが、今回の目的には不適と思い至ったので。
Perl暦がまだ浅いのでそこら辺の判断もうまくできませんでした。失礼。m(_ _)m
No.3
- 回答日時:
一番簡単な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以下の文字は英字とみなす。
}
}
}
No.2
- 回答日時:
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で記述されたテキストから日本語(=全角部分)を抽出して別ファイルへ書き込む」
ということを考えてます。
よろしくお願いいたします。
No.1
- 回答日時:
そのテキスト中の日本語の文字コードは何でしょうか?
それさえ分かっていれば正規表現で抜き出せます。
以下を参照してください。
http://www.din.or.jp/~ohzaki/perl.htm#Character
参考URL:http://www.din.or.jp/~ohzaki/perl.htm#Character
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Ruby パイソンプログラミング 2 2022/12/03 18:44
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- その他(ネットショッピング・通販・ECサイト) 海外のネットショッピングで 買う時までは 日本語標記に 変換できたのですが 商品を買って 自分のメー 4 2022/08/02 06:04
- 英語 海外のネットショッピングで 買う時までは 日本語標記に 変換できたのですが 商品を買って 自分のメー 2 2022/08/02 06:00
- Mac OS iMacでコマンドラインと辞書を連携させる方法 2 2023/07/15 17:59
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- UNIX・Linux gawk 3 2022/08/18 14:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
awkスクリプトでダブルクォーテ...
-
ファイル出力の改行コードをLFに
-
sprintfで10進数を桁数指定で16...
-
Perl中で teeを使っても戻り値...
-
sprintfについて
-
DOSコマンドで、標準出力を出力...
-
Perlでファイルの末尾から指定...
-
ListBoxのデータを高速でファイ...
-
ExcelをCSV書き出す場合のシー...
-
C言語で特定の行を抽出する方法...
-
window.open でのファイル指定方法
-
パスから最後のディレクトリだ...
-
fgets で値が取得できない
-
ReadLineでの読み出し行を指定する
-
CSVデータの編集の際の重複チェ...
-
ifstream を利用した1行分のテ...
-
vba dir の相対パス
-
配列の中に重複文字列があるか...
-
オープンしたファイルで行の連結
-
perlで、後ろの行を読んで、前...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
awkスクリプトでダブルクォーテ...
-
DOSコマンドで、標準出力を出力...
-
重複するデータを抽出できる秀...
-
Perlでファイルの末尾から指定...
-
sprintfについて
-
[Perl]ファイル出力のエンコー...
-
エクセルVBAで素数だけを出力す...
-
文字コードの変換(Shift-JISか...
-
テキストファイルから日本語部...
-
sprintfで10進数を桁数指定で16...
-
ファイル出力の改行コードをLFに
-
Perlからsyslog経由でログを出...
-
PerlからのCSV出力
-
perlでcsvの出力について
-
教えて!perlから.exeファイル...
-
バッチファイルで、記号を含む...
-
perl CGIでのhttpヘッダー出力...
-
print文で&(半角)文字のエラー...
-
Perlでエラーログに日時をつける
-
紙にもホームページにも同じレ...
おすすめ情報