- ベストアンサー
変数に格納できる文字数の限界
お世話になります。 題名の通り、Perlで変数に格納できる文字数の限界は あるのでしょうか? 100文字くらいの文章を変数に入れることができません。こういった場合はどうしたらいいかアドバイスを頂けませんでしょうか。 $shou=$1 if/\{第1章\}(.*?)/; というように{第1章}に続く文章(大体100字くらい)を抽出して、それを変数に入れたいのですが、 $shouを表示させようとしても何も表示されません。 どうぞよろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
#2 です。 力技ですが。。 in_data.txt {第1章} aaaaaaaaaaaa。\\bbbbbbbbb ccccccccccccccccccc。\\ {第2章} ddddddddddddddd。\\eeeeeeeeeee fffffff。\\ggggggggggggggggggggggggggg。\\ スクリプト #!/usr/local/bin/perl $fin = "in_data.txt"; $s = ""; @t = (); # ファイルを読み込みつつ、@tへ取り込む open(IN, $fin) or die "open error."; while(<IN>) { chop; if ($_ =~ /{第(\d+)章}/) { $s = $1; } else { $t[$s] .= $_; } } close(IN); # テスト表示をする。 for $i (0 .. scalar(@t)-1) { if ($t[$i] ne "") { print "第${i}章\n"; print $t[$i]. "\n"; } } 結果 第1章 aaaaaaaaaaaa。\\bbbbbbbbbccccccccccccccccccc。\\ 第2章 ddddddddddddddd。\\eeeeeeeeeeefffffff。\\ggggggggggggggggggggggggggg。\\ って感じになりました。 このスクリプトでは、章番号をキーとした配列 @t を作り、 その中に取り込んでいます。 目的は、こんな事でしょうか?
その他の回答 (5)
- arcsin
- ベストアンサー率70% (28/40)
何度もごめんなさい。 #4で答えた内容から、#3の回答は無かったことにしてください(改行が\nという前提で話してしまったので)ただ、参考プログラムをそのままコピペしたらちゃんと動作したのですが・・、file.txt の中身は具体的にどういう感じの文章が入っているのでしょう。私は {第1章}aaa\\bbb\\cc {第2章}ddd\\eee\\ff という中身にして調べてみました。
お礼
arcsin様、こちらこそ謝らなくてはいけません。 file.txtの中身は具体的にこのようになっています。 ------------------------ {第1章} aaaaaaaaaaaa。\\bbbbbbbbb ccccccccccccccccccc。\\ {第2章} ddddddddddddddd。\\eeeeeeeeeee fffffff。\\ggggggggggggggggggggggggggg。\\ ----------------------------------------------- ですので、最初にarcsin様がおっしゃったように 改行(\n)が含まれるのですね。\\で改行を表すことにしているのですが、file.txtでは無関係でした。すみませんでした。file.txt自体の改行は上記のように、{第1章}の次、・・・bの次、・・・c。\\の次、・・・というようになっております。 それで、#1でのスクリプトを実行してみると、何も表示されません。 試しにfile.txtを ------------------------ {第1章}aaaaaaaaaaaa。\\bbbbbbbbb ccccccccccccccccccc。\\ {第2章} --------------------------------- というようにしてみるとaaaaaaaaaaaa。\\bbbbbbbbbだけ表示されました。なので、最初にやったのはやはり入っていないのですね。 そもそもの正規表現$shou=$1 if/\{第1章\}(.*)/s;がまずいのでしょうか?file.txtでは{第1章\}のあとに 改行が入っているからだめなのですね。if/\{第1章\}\n(.*)/s;と変えてみましたが、表示されませんでした。 #3で教えていただきました方法について、これから試してみます。
- arcsin
- ベストアンサー率70% (28/40)
> 改行は含んでいるのですが、(\n)ではなく (\\)で行っているのですが、そのときの オプションもsをくっつけるのでしょうか? 答え忘れていました。コレについて、(\\)で改行を行っているというのはどういうことでしょうか・・?改行の変わりに「\\」という文字を使っているということですか?もしそうであれば、sはいらないと思います。ちょっとこれに関しては私の知識不足かもしれないので違うようでしたら他の方にオマカセということで・・・。
- arcsin
- ベストアンサー率70% (28/40)
while(<IN>){ $shou=$1 if/\{第1章\}(.*)/s; s/\{第1章\}(.*)/$1/s; print OUT; } この部分ですが、while(<IN>)は標準入力を改行ごとにわけながら$_に値を代入していきます。 なので、たとえば ---kekka1.txt---------- {第一章} あいうえお かきくけこ ----------------------- であれば、最初のループでは、$_に「{第一章}\n」が代入され、その次のループで「あいうえお」が代入され・・という風に1行ずつループします。 なので、最初のループで $shou=$1 if/\{第1章\}(.*)/s; にマッチしたといえども、元の$_が「{第一章}\n」なので、$shouには何も入ってないように見えます。そうならないようにするためには最初に、 while($_ .= <IN>){} 等して一度変数に文章を全部詰めるべきだと思います。(上の表記は適当なので間違ってるかも)
- Dpop
- ベストアンサー率51% (279/544)
多分、#1さんの回答で良いと思うので、それは置いといて。 変数に入る文字数の方ですか。 Perlの文法自体には文字数の規定はありません。 そのため、スカラー変数に入る文字数は実装環境や実行時のメモリ容量によって決まります。
お礼
Dpop様、回答して下さりありがとうございます。 変数の中の値(文章)が表示されないので、文字数制限があるのかと思ってしまいました。 下に書かせていただきましたが、アドバイスいただけないでしょうか。よろしくお願いします。
- arcsin
- ベストアンサー率70% (28/40)
まず文章とおっしゃっているので、 $_には改行(\n)を含む文字列が入っているんですよね? 正規表現でオプションを何もつけないと「.」は「改行を含まない任意の文字」の意味になります。なので「改行を含む任意の文字」にするため(複数行モード?)に、オプションsをくっつけます。 さらに(.*?)の「?」は最小マッチといって、「.*」の正規表現を満たす最小マッチだけ取得します。「.*」は任意文字の0以上の繰り返しを意味しますから、この最小マッチは「任意の文字の0回の繰り返し」つまり何も無いものがマッチしてしまうので$1には何もきません。(?についてはあまりしらないのでもしかしたらこの解説は違うかもしれません) なのでこの?もとってやりましょう。つまり、 $shou=$1 if/\{第1章\}(.*)/s; が正しい記述になります。
お礼
arcsin様、回答を下さりありがとうございます。 >$_には改行(\n)を含む文字列が入っているんですよね? すみません、最初に書くのを忘れてしまいました。 改行は含んでいるのですが、(\n)ではなく (\\)で行っているのですが、そのときの オプションもsをくっつけるのでしょうか? $shou=$1 if/\{第1章\}(.*)/s; として、行ったのですがブラウザに表示されませ ん。 ---------------- #!C:\Perl\bin\perl use CGI; my $form = CGI->new; $form->charset('Shift_JIS'); print $form->header(-type => "text/html"); open(IN,"<file.txt"); open(OUT,">kekka1.txt"); while(<IN>){ $shou=$1 if/\{第1章\}(.*)/s; s/\{第1章\}(.*)/$1/s; print OUT; } close(OUT); close(IN); print $shou; ------------------- というスクリプトなのですが、kekka1.txtで確認すると{第1章}の次に続く文章の抽出には成功しています。 なぜ$shouに入っていないのでしょうか?(表示されないのでしょうか?) よろしくお願いします。
お礼
Dpop様、回答下さりありがとうございます。 教えていただきましたプログラムを実行してみましたところ、目的のものが表示できました。章番号をキーとした配列 @tを使うと第1章だけでなくその後の章も 取り出して表示できるのですね。 本当に助かりました。ありがとうございます。