すごく基本的なことで恥ずかしいのですが、
条件を満たす配列の要素を結合し、元の配列に返す方法がわかりません。

foreach $aa (@aa) {
if ($aa =~ /-/){

}
}
とまでは考えたのですが・・・
どなたかお分かりの方、よろしくおねがいします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

ああ、そういうことをおやりになりたかったんですか。


もちろん、「[」が出てきたときに一時変数に入れ、「]」が
出てきたときにまとめてpushして次の要素に備える…でも
できますね。練習としてチャレンジしてみてもよろしいでしょう。

別解として、私なら
@aa = (join('', @aa) =~ /\[.*?\]/g);
ですかね。
ちょっと古いPerlなら
@aa = (join('', @aa) =~ /\[[^\]]*\]/g);
かな。わざと1行で書いてみました。解説が必要なら遠慮なく
おっしゃってください。しかしいろんな書き方ができますねえ、
Perlは。まさにThere Is More Than One Way To Do Itですな。
    • good
    • 0
この回答へのお礼

無理やりやったらなんとか出来ました(^^;
修正は来週の土日まで持越しです。
こんなのでもプログラミングができるなんて、
ほんとTIMTOWTDIのおかげですね。

お礼日時:2001/05/13 23:49

または、条件を満たすものを文字列として「結合」させ、


満たさない要素はそのままコピーする、というのなら
foreach $aa (@aa) {
if ($aa =~ /-/) {
$tmp .= $aa;
} else {
push(@bb, $aa);
}
}
push(@bb, $tmp);
などのやりかたがありますね。文字列結合して貯めていた$tmp
を最後に@bbの末尾要素として付け加える方法です。

[余談]
これこれこういうデータが、最終的にこうなってほしい、と
はっきり書いてあるとすごくわかりやすい質問となると思いますよ。
    • good
    • 0
この回答へのお礼

すばやい回答ありがとうございます。
pushを使ってできそうですので、考えてみます。

お礼日時:2001/05/13 19:44

ええと、結合というのがよくわかりませんが、それは


@aa = ('aaa', 'abc-d', 'sss', 'xx-yy', 'z-');
だったとき
@aa = ('abc-d', 'xx-yy', 'z-');
と/-/にマッチするものだけにしたい、という意味でしょうか?

ならば、別の配列を用意してそこに条件が合ったものだけコピーして、
最後に元の配列にまるごと移すようにするのはどうでしょう。

foreach $aa (@aa) {
if ($aa =~ /-/) {
push(@bb, $aa);
}
}
@aa = @bb;

なお、これと同じことを1行で書けるgrepというものがあります。
@aa = grep {/-/} @aa;
どちらでもお好きなほうをどうぞ。

もしお使いの本にgrepの解説がないのなら、それはかなり昔の書物なので
廃棄しても基本的に問題ありません。

この回答への補足

回答ありがとうございます。
説明不足で申し訳ありません。

具体的にいうと、
@aa = ('[abc', 'def]', '[ghi]', '[jkl', 'nmo', 'pqr]');

@aa = ('[abcdef]', '[ghi]', '[jklnmopqr]');
にしたいのです。

補足日時:2001/05/13 19:23
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

QCan't use string ("0") as an ARRAY ref の原因について

Perl 5.6を使っております。
Perlで原因不明なエラーに直面して困っております。
Can't use string ("0") as an ARRAY ref while "strict refs"
というエラーが発生しているのですが
これは良くあるミスとして何が原因でしょうか?

Aベストアンサー

No.2です。書き漏らしてましたが、エラーメッセージの内容がよくわからない時は

use diagnostics;

しましょう。

QPerlのexitについて

こんにちは、現在シェルスクリプトからperlを呼び出し、
その実行結果を受け取るというシンプルな所で悩んでいます。

Perlからプログラムの終了時にexitで
値を返しているのですが、どの値を返しても0が返ってきます。
受け取り側はシェルスクリプトです。
exitには何か特殊な要素があるのでしょうか?
ご存知の方がいたらご教授下さい。
よろしくお願いします。

#
#perlのソース
#(i=0の場合・i=1の場合)
#

if(i == 1) {
exit 1;
}
exit 0;

Aベストアンサー

No1です。
if(i == 1) {
exit 1;
}
は、if($i == 1)の間違いでしょう。
$i = 1;とすると$iに1がセットされますが、
i = 1;でiに1をセットしたことにはなりません。(セット出来ません)
従って、exit 0;が実行されます。
但し、念のため、exit 1;の行のみを生かし、ほかは全てコメントにして実行してみたらどうでしょうか。それで0が表示されるようでしたら、シェル側の問題だと思います。

Q行頭と行末に文字追加

文字変換がうまくいきません。
sedとawkもしくはperlを使ってなんとかならないでしょうか?
行の行頭と行末を " で囲みたいのですが。

------test.txt-----
abc cde fgh
hijk lm
nopq rstu vwx y z
------test.txt----

以下のように。
"abc cde fgh"
"hijk lm"
"nopq rstu vwx y z"

よろしくお願いします。

Aベストアンサー

例えばこんな感じ:

sed -e 's/^/"/;s/$/"/' test.txt
awk '{$0="?"" $0 "?"";print}' test.txt
perl -pe 's/^/"/;s/$/"/;' test.txt

シングルクォートによるコマンド引数指定ができない場合は別途エスケープする必要があります。

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

Qperl でエラー:Wide character in・・・とは何がいけないのでしょう?

エラーメッセージ:
Wide character in subroutine entry at C:/Perl64/lib/Encode.pm line 221.

この意味と対応策を教えてください。

Aベストアンサー

(昨今の)Perlには「utf8フラグ」なるものがあります。


通常、日本語の仮名や漢字は、複数の文字を組み合わせて表現しています。
例えば、「ア」という文字は
Shift_JISなら \x83\x41 という「2文字」
UTF-8なら \xE3\x82\xA2 という「3文字」
です。
この状態は、1バイト1バイトの文字が並んでいる状態なので、「バイト列」と呼ぶことにします。(バイナリと呼んだりもします)
ファイルには、この形で入っています。

この方式だと、「ア」が1文字として扱われずいろいろと不便です。
例えば、 Shift_JISのアに含まれる \x41 はASCIIコードでのAです。
ここで、s/A/B/ とすると、 AがBに書き変わるだけでなく、ア( \x83\x41)がィ (\x83\x42)に書き変わってしまいます。

そこで、これらを統一扱う「内部形式」というのを作りました。
それが「utf8フラグ付き文字列」です。

読み込み時は
 ファイルや文字列変数でのバイト列 → 復号( decode ) → 内部形式(utf8フラグ付き文字列)
書き出し時には
 内部形式 → 符号(encode) → ファイルや文字列変数でのバイト列
とすることで、内部形式では「ア」を一文字として扱うことができます。s/A/B/としてもアには影響ありません。

復号/符号 は入出力時に自動で行なうようにしたり、Encodeモジュールのdecode,encode等を使用して明示的に行なったりします。

この書き出しの時に、
 内部形式 → 符号(encode) → ファイルや文字列変数でのバイト列
としなければならないところを
 内部形式 → ファイルや文字列変数
と直接おこなってしまった場合、そんなことはできない、と発生するのが「 wide character 〜」の警告です。


対処法は、 上記のようにencodeすることです。
また、場合によっては decode を抑制して 最初からバイト列で扱う方が正しいこともあります。
具体的なことは、実際のコードとやろうとしていることがわかならないと答えられません。

(昨今の)Perlには「utf8フラグ」なるものがあります。


通常、日本語の仮名や漢字は、複数の文字を組み合わせて表現しています。
例えば、「ア」という文字は
Shift_JISなら \x83\x41 という「2文字」
UTF-8なら \xE3\x82\xA2 という「3文字」
です。
この状態は、1バイト1バイトの文字が並んでいる状態なので、「バイト列」と呼ぶことにします。(バイナリと呼んだりもします)
ファイルには、この形で入っています。

この方式だと、「ア」が1文字として扱われずいろいろと不便です。
例えば、 Shift_JISのアに...続きを読む

Qファイルのワイルドカードについて

ファイルの存在をワイルドカードで指定したいのですが、どのような書き方でできますでしょうか。

$file="home/hoge1.txt";
if(-f $file){print"存在します。";}

上記の場合、hoge1.txtの部分をワイルドカードを使って、hoge*.txtとしたいのですが、うまく結果が得られません。

この場合の書き方を教えていただけないでしょうか。

よろしくお願いします。

Aベストアンサー

glob関数やFile::Globモジュールを使って、ファイル一覧のリストを取得
→ リストの各要素について -f で調べる

http://perldoc.jp/func/glob
http://perldoc.perl.org/File/Glob.html


人気Q&Aランキング