プロが教える店舗&オフィスのセキュリティ対策術

スミマセン。基本だと思いますが、教えてください。

Joyful系の掲示板のファイルなのですが、
各記事の親記事にある特定のデータを、
取り出す方法を教えて下さい。


5<>IP<>1234567890<>
3<><>2012/01/12(Thu) 08:42<>ウサギ<>Yahoo<>
5<>3<>2012/01/12(Thu) 09:04<>ネコ<><>
1<><>2012/01/12(Thu) 08:41<>イヌ<>Google<>
2<>1<>2012/01/12(Thu) 08:41<>ウサギ<><>
4<>1<>2012/01/12(Thu) 09:03<>タヌキ<><>

こんな感じで、データが記入されるdatファイルがあります。
「1のレスが2・4」「3のレスが5」です。


それで、親記事に「Yahoo」や「Google」というデータが入っているので、
親記事1にレスしてる2・4でも、
親記事に入ってる「Google」といった文字を反映したいのです。


うまく伝えられ無いので、画像にしてみましたので見てやって下さい。


私が見てるプログラムでは、
レスはレスで、「Google」等の文字を探してしまっているので、望む形にならないのです;
どうぞ、よろしくお願いします!

↓ざっくり。この辺りの最初の方に、親だけ読み込んで、$search1 とかに、セットできないかと考えています。
★━━━━━━━━━━━━━━━━━━━━★
local($ipt,$wh,$i,$flag);

# 記事を展開
open(IN,"$logfile") || &error("Open Error : $logfile");
$top = <IN>;
$i=0;
$x=1;
$flag=0;

# ソート無し:必要最小限だけ読み込み
if(!$sort && !$threadsuu){
while(<IN>){
if((split(/<>/))[1] eq "") { $i++; }
if ($i < $page + 1) { next; }
if ($i > $page + $p_log) { next; }
push(@DATA,$_);
}
}

# ソート無し、スレッド表示有り
elsif(!$sort && $threadsuu){
@DATA = <IN>;
}

# ソート有り:全データを読み込んでソート実行
else{
@DATA = <IN>;
if($sort == 1){ &ressort; }
if($sort == 2){ &nosort; }
}
close(IN);

# 新着スレッドを表示
if($threadsuu || $up_down){ &thread; }

# レスの表示制限をする場合には、配列を改造
if($max_res){ &omit; }
foreach(@DATA){
($no,$reno,$date,$name,$mail,$search) = split(/<>/);

# ページ処理
if($sort || $threadsuu){
if ($reno eq "") { $i++; }
if ($i < $page + 1) { next; }
if ($i > $page + $p_log) { next; }
}

if (!$reno && $flag) {
print "</td></tr></table><br><br>\n\n";
$flag=1;
}
if (!$reno) {
print "<table class=\"table1\" align=\"center\" cellspacing=0 cellpadding=2>\n<tr><td>";
$flag=1;
}

if ($reno && $line_color) { print "<hr noshade size=1 width='85%' color=\"$line_color\">\n"; }
print "<table width=100% border=0 cellpadding=2 cellspacing=0>\n<tr>";
if ($reno) { print "<td rowspan=2 width=40><br></td>"; }

if($line_color){ print"<td>"; }
elsif($reno){ print"<td class=\"b2\">"; }
else{ print"<td class=\"b1\">"; }

if (!$reno) { print "<span class=\"sub\"> <font color=\"$t_color\"><b>$sub </b></font></span>";}
else { print "Re:<font color=\"$t_color\"><b>$sub </b></font></span>";}


if($search == "yahoo"){ print "投稿者:<span class=\"name\">$name</span> yahooで検索";}
elsif($search == "google"){ print "投稿者:<span class=\"name\">$name</span> Googleで検索";}
else{ print "投稿者:<span class=\"name\">$name</span> その他で検索";}

「掲示板で親のデータを子に反映させる方法」の質問画像

A 回答 (3件)

「その処理をしたいところ」で #2 の getData を除いた部分を実行すれば, @data に処理したあとのデータが入る, はずです. そのデータは結局, もとと同じく


3<><>2012/01/12(Thu) 08:42<>ウサギ<>Yahoo<>
のような形になっているだけですから, その「表示」は既にできているはずじゃないですかね.

この回答への補足

何度もありがとうございますm(_ _)m

print "$i";
って事ですよね?

残念ながら、上から一番目の記事に1,2番目の記事に2・・・・・という感じで通し番号が表示されるだけで、親のデータが表示されたりはしませんでした;
何か、記入時に間違っていそうな点が有りましたら、教えて頂けると嬉しいです(^_^;)

補足日時:2012/01/14 14:37
    • good
    • 0
この回答へのお礼

ありがとうございます。
ちょっと錯乱してきたので、
質問内容を変えて、改めて質問することにします。
大変お世話になりました!(^^)
また、宜しければ、お願いいたします。

お礼日時:2012/01/15 14:18

とりあえず @data に各行のデータが入っているとして,


my @ids;
for my $i (0 .. $#data-1) {
my $id = (split /<>/, $data[$i])[0];
$ids[$id] = $i;
}
で「ID→行番号」のインデックスを作る. で, これらの情報を元に
sub getData {
my $thisId = shift;
my @infos = split /<>/, $data[$ids[$thisId]];
if ($infos[1] ne '') {
$infos[4] = getData($infos[1]);
$data[$ids[$thisId]] = join('<>', @infos);
}
$infos[4];
}
のように再帰的に親記事の情報をとってくるサブルーチンを作って
for my $i (0 .. $#data-1) {
getData($i);
}
でできる... かなぁ. 何も考えずに作ってるからできるかどうかわからないし効率もよくない (「自分を『レス』している記事」を記録して, それを使って配っていく方が効率的) けど, イメージとしては「親記事の情報を再帰的にとってくる」だけでできるはず.

なお, local を使うとスコープがあやしいのでできれば my を使う方がよいと思います.

この回答への補足

ありがとうございます(^^)

もう少し、教えてください;
記入の場所と、データを表示させる方法を教えて頂けませんか?

今のところこんな感じです。
*-----------------*

sub getData {
my $thisId = shift;
my @infos = split /<>/, $data[$ids[$thisId]];
if ($infos[1] ne '') {
$infos[5] = getData($infos[1]);
$data[$ids[$thisId]] = join('<>', @infos);
}
$infos[5];
}


sub html_log {
local($ipt,$wh,$i,$flag);

# ヘッダを出力
&header;

# 上部メニュー
&headmenu;

# 記事を展開
open(IN,"$logfile") || &error("Open Error : $logfile");
$top = <IN>;
$i=0;
$x=1;
$flag=0;

# ソート無し:必要最小限だけ読み込み
if(!$sort && !$threadsuu){
while(<IN>){
if((split(/<>/))[1] eq "") { $i++; }
if ($i < $page + 1) { next; }
if ($i > $page + $p_log) { next; }
push(@DATA,$_);
}
}

# ソート無し、スレッド表示有り
elsif(!$sort && $threadsuu){
@DATA = <IN>;
}

# ソート有り:全データを読み込んでソート実行
else{
@DATA = <IN>;
if($sort == 1){ &ressort; }
if($sort == 2){ &nosort; }
}
close(IN);

# 新着スレッドを表示
if($threadsuu || $up_down){ &thread; }

# レスの表示制限をする場合には、配列を改造
if($max_res){ &omit; }
foreach(@DATA){
($no,$reno,$date,$name,$mail,$search) = split(/<>/);

# ページ処理
if($sort || $threadsuu){
if ($reno eq "") { $i++; }
if ($i < $page + 1) { next; }
if ($i > $page + $p_log) { next; }
}

if (!$reno && $flag) {
print "</td></tr></table><br><br>\n\n";
$flag=1;
}
if (!$reno) {
print "<table class=\"table1\" align=\"center\" cellspacing=0 cellpadding=2>\n<tr><td>";
$flag=1;
}

if ($reno && $line_color) { print "<hr noshade size=1 width='85%' color=\"$line_color\">\n"; }
print "<table width=100% border=0 cellpadding=2 cellspacing=0>\n<tr>";
if ($reno) { print "<td rowspan=2 width=40><br></td>"; }

if($line_color){ print"<td>"; }
elsif($reno){ print"<td class=\"b2\">"; }
else{ print"<td class=\"b1\">"; }

if (!$reno) { print "<span class=\"sub\"> <a name=\"$no\">$mark</a><font color=\"$t_color\"><b>$sub </b></font></span><br>";}
else { print "<span class=\"sub\">$re_mark<font color=\"$t_color\"><b>$sub </b></font></span><br>";}

my @ids;
for my $i (0 .. $#data-1) {
my $id = (split /<>/, $data[$i])[0];
$ids[$id] = $i;
}

for my $i (0 .. $#data-1) {
getData($i);
}
print "getData($i)";

}
*-----------------*
print "getData($i)";←絶対違うと思うのですが、わからなくて;
どうぞ、よろしくお願いします!

補足日時:2012/01/13 14:06
    • good
    • 0

確認したいことがあります:


・あなたが使っている Perl のバージョンは?
・「レス」で違うデータが入っているときはどうすればいいですか?
・入力と同じ順序で出力したいですか?

この回答への補足

ご返答、ありがとうございます!(^^)

1.Perlのバージョン
  さくらインターネットを使っています。
  「5.8.x」のようです。


2.「レス」で違うデータが入っているとき

  レスに入っているデータは一切無視で、
  親記事のデータを使わせたいです。


3.入力と同じ順序

  これは、親記事やレスの順番を、
  古い順で上から表示するという意味ですか?
  可能であれば、新しくレスが付いたら、一番上に
  表示できたら嬉しいです。
  (ご質問の意味を間違って捉えていましたら申し訳ありません;)


どうぞ、よろしくお願いします!

補足日時:2012/01/12 20:57
    • good
    • 0

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