プログラム初心者なので、あまりうまく説明できませんが、よろしくお願いします。
あるテキストデータから、一部分だけをだけを取り出したいのです。
例えば、
例1
■見出し1■
・データ1
・データ1
■見出し2■
・データ2
・データ2
■見出し3■
・データ3
・データ3
のようなデータから、■見出し2■とその中にある内容(・データ2の内容は
いくつもあるものとする)でだけを取り出したいのですが、どうすれば
よいのでしょうか?■見出し*■をkeyとしてハッシュに入れて、複数個
の値をつればようのでしょうか?
それとも、他の方法で処理したほうがよいのでしょうか?
文字列から文字列までの指定というのは、どうすればよいのでしょうか?
回答よろしくお願いします。
No.2
- 回答日時:
今一つ質問の内容が理解できていないのですが,一応「Perlで多次元配列を実現したい」というふうに解釈しました。
Perlはnativeには多次元配列をサポートしてませんので,ふつうは join() と split() を使って疑似的に多次元配列的な操作を実現してやります。
join() は配列を文字列に変換する関数,split() は文字列を配列に変換する関数で,以下のように使います。
#↓元の配列
@midashi_array = ("データ", "データ", "データ");
#↓最初の '\n' は区切り文字。何でもいいが配列の値("データ")の中に含まれていないもの)
$midashi_str = join('\n', @midashi_array);
#↓これで文字列が配列に戻る。配列 @midashi_array と @midashi_array_new は同じ値を持つはず
@midashi_array_new = split('\n', $midashi_str);
あとはこれをcassis_rさんが考えておられるように"見出し"をキーに持つハッシュ(Perl用語だと「連想配列」)と組み合わせればご所望の処理は実現できると思います。
◆値の格納
@midashi1 = ("データ1", "データ1", "データ1");
$midashi1_str = join('\n', @midashi1);
$hash{'見出し1'} = $midashi1_str;
...
◆値の取り出し
$midashi1_str = $hash{'見出し1'};
@midashi1 = split('\n', $midashi1_str);
...
これをループで回すなり何なりして処理すればできると思います。
この回答への補足
回答ありがとうございました。
前回、私の問題に対する質問が曖昧だったので今回は、具体的に行いたかった処理補足させていただいきます。
No.1の回答者の方のところにも補足させていただいたので詳しい内容は、省略させていただきますが、他人が作ったHP(もちろん許可は頂いてあります)から欲しいデータだけを取り出したいのです。
そのための処理を行うのには、どうすれば効率が良いかなどを、もう一度よろしければ、お力を借りたいと思います。
あつかましいのですが、よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
むちゃくちゃ長くて申し訳ありません。
回答しようとしてみて、いろいろなことが気になってしまって長くなりました。
間違いはないように努力していますが、もっといい解決方法はあるかも知れません。
ハッシュのキーは、重複が許されません。
1つのユニークなキーに対して、1つの値しか対応が付けられません。
ただし、値の型には参照も許されるので、リストの参照を対応づけすることも可能なはずです。回答者は、ややこしくなるのでやったことがないのですけど。
■見出し2■
・データ2
・データ2
のように、同じものが並んでいるように書いてありますが、並んでいるデータ2の内容は同じものですか?
それとも、何種類かありますか?
同じ種類のが何行かあるとして、それはまとめて1つにしてもいいですか?
1種類で、まとめてもOKなのであれば、単純にハッシュにすれば可能だと思います。
最後に結びつけた値がキーに対応する値になります。
■見出し1■ => ・データ1
■見出し2■ => ・データ2
データに複数種類が可能だとすると、ハッシュでは対応できないと思います。
・データ? の内容が■見出し?■に関係なくすべてのデータ内でユニークであることが確実なのであれば、キーと値の関係を逆にすることで検索可能だと思います。
・データ1(その1) => ■見出し1■
・データ1(その2) => ■見出し1■
・データ2(その1) => ■見出し2■
上記のいずれでもない場合は、下記のような感じで一つ一つ見ていくしかないと思います。
データが多い・検索回数が多い場合は重たい処理になるかも知れません。
その場合には DB を使うなり、もっと扱いやすい形式に変換するなりした方がいいと思います。
下記ではカンマ区切りのテキストデータで返していますが、#★ 以下のように変更すれば、配列(の参照)でも値を返せます。
特にカンマ区切りにする必要も、改行をとる必要もありませんが、この方が見栄えがいい(というか、ファイルに出力した際に使いやすそうな)のでそうしています。
各データの行を区別して扱う必要がない(複数まとめて扱いたい)のであれば、単純に連結してもOK です。
改行で切り分けることもできます(split(/\n/, 複数行データ))。
文字列の検索については "perl" と "正規表現" で検索してみると、いろいろ見つかると思います。
数字なので、(.+) ではなく(\d+) でもいいかと思いましたが、どうやら全角数字は駄目みたいです。
↓以下がスクリプトです。
#/usr/bin/perl
# データをグローバル変数 @data に読み込む
open(IN, "データファイル名") || die "データファイル名 open 失敗\n.";
my $key = "";
@data = ;
close;
my $val;
my $ii;
$val = kensaku("1");
foreach $ii (split(/,/,$val)) {#★ foreach $ii (@$val) {
print $ii . "\n" ;
}
exit;
# メモリ内を検索する
sub kensaku {
my $num = $_[0];# 引数: 見出し番号(全角/半角に注意)
my $line;# 現在行
my $value = ""; #★ my @value;
foreach $line (@data) {
if ($line =~ /■見出し$num■/) { #目的の見出し
$key = $line;
}
elsif ($line =~ /■見出し(.+)■/) { #目的外の見出し
$key = "";
}
else { # 見出し以外
if ($key ne "") { # 目的の見出し以下のデータ項目
chop $line; # 改行を取る。場合によって取らないことも可
if ($value eq "") { # 最初
$value = $line;
}
else {# 2 個め以降は区切り文字 "," で区切って連結
$value =. "," . $line
}
#★ if で場合分けせずに push @value, $line;
}
}
}
return $value; #★ return \@value;
}
この回答への補足
返答が遅くなってしまって申し訳ありません。
丁重な説明をして頂き、誠にありがとうございました。
今回、私がやりたい事は、多くの情報の中から、知りたい情報だけをを抜きだしてきて、それを携帯電話などのモバイル機器でも見やすくするように、編集できないかと考えています。
例えば学校などのHPなどで連絡事項のページがあったとすると、その大きな連絡事項群の中から、例えば、「休講情報」について知りたいとします。
それを、携帯でも情報を見やすくするために、余計なものを取り除いて、「休講情報」だけの、新しい容量の小さいwebページを作りたいのです。
ここで、情報源となるHTMLページには、休講情報の内容の数や範囲などは、こちらでは全く指定できません。
そのための処理をしたいのですがどうもうまくいきませんでした。タブと余計なスペースなどを削除することはできたのですが(本に書いてあった通りに書いただけですけど)、この1番メインとなる処理がうまくいきませんでした。
そこで、読み込んだデータから、部分的な抜き出し方法が知りたかったのです。
キーとなるものも、もしかしたら変化するかも知れませんし、その中の内容は、
もちろん変わってしまうと考えられます。扱いずらいデータですよね。。。。
先日、例としてあげたデータのように、どこかマークの間にはさまれている文字が
見出しとなっており、その後に書かれているものが内容だということは、変わらな
いと思います。
もし、このようなデータを処理するのに良い方法がありましたら、御教授お願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) vba 等間隔の列に対しての計算 6 2022/05/17 20:15
- Excel(エクセル) 【Excel】指定した文字列に該当する行を重複しないようにリスト 3 2022/03/30 12:27
- Visual Basic(VBA) 複数ファイルのデータの統合について 12 2022/05/14 12:03
- Excel(エクセル) 関数EXACT(文字列,文字列)とexcelVBA 3 2022/04/14 15:07
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- Excel(エクセル) エクセルで沢山のレコードの最後に追記するには? 7 2023/04/10 13:27
- Visual Basic(VBA) エクセルについて教えてください。 3 2023/06/28 09:11
- その他(プログラミング・Web制作) プログラミング python pandas 固定長データの出力 2 2022/08/16 11:22
- Excel(エクセル) エクセルで飛び飛びのセルの計算 5 2022/10/25 05:33
- システム CSVファイルのマッピング処理の省力化 1 2022/11/24 00:01
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列のサイズを動的に拡張
-
Pythonの再帰関数の動作の流れ...
-
文字列をカウントする方法
-
ファイル全てを .xlsm に変更し...
-
一定時間が経過したフォルダの削除
-
csvファイルの横方向への改行に...
-
while(<ハンドラ>) {} で行数を...
-
画像アップロード機能を追加し...
-
batファイルでrenameができませ...
-
while文がうまく動かない
-
VBAでCSVファイルの特定行を書...
-
MATLABのm-fileについて
-
ディレクトリのファイル作成を...
-
ANSI Cでファイル名、ディレク...
-
VB6.0でDB接続する際に切断時の...
-
AutoCADのスクリプト
-
C++でファイルから複数行のデー...
-
オープンしたファイルで行の連結
-
Perlで特定行から特定行までを...
-
連番のファイルを何個も開きたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列の中に重複文字列があるか...
-
C言語のバイナリモードでのfsca...
-
データの日付でソートをしたい
-
perlで複数行のデータを自由に...
-
perl-cgi 文字の長さでソートし...
-
Visual C++を用いたシリアル通信
-
バッチファイルの作り方(CSV→...
-
awkスクリプトでダブルクォーテ...
-
VBAでCSVファイルの特定行を書...
-
DOSコマンドで、標準出力を出力...
-
ExcelをCSV書き出す場合のシー...
-
openした後、closeしないでプロ...
-
close()で例外が投げられる理由
-
batファイルでrenameができませ...
-
VBAでCSVファイルを途中行まで...
-
window.open でのファイル指定方法
-
VBAで巨大なファイルの途中から...
-
Perlで特定行から特定行までを...
-
ReadLineでの読み出し行を指定する
-
エクセルVBAで素数だけを出力す...
おすすめ情報