Perlコーディング初心者質問スレ Part 54
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2007/02/10(土) 19:21:23ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc10.2ch.net/test/read.cgi/php/1164519503/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0264216
2007/03/04(日) 21:04:47ID:cYBOup8B0266nobodyさん
2007/03/05(月) 09:19:57ID:???ソースはこんな感じです。
$message =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1<a href="$2" rel="nofollow">$2<\/a>/g;
(質問1)
([^=^\"]|^) についてです。
前者の ^ は 「を含まない」 を意味し、後者の ^ は行の先頭を意味するものだと思います。
(ただ、1行ずつ処理しているわけではなく $message には記事の全てが入っているので、記事の最初という意味になります。)
そして、[^=^\"] の 2番目の ^ は、単なる リテラル(普通の文字) として扱われますよね。
これは、'=' と '^' と '"' を含んでいないという意味になるはずですが、記事の最初に '=' とかがあったとしても、
正しくリンク処理されます。
これは何故でしょうか?
(質問2)
Firefox だと 長いURLが折り返されないので、URL が 81文字以上になった場合に、
$2 の部分を80文字 + "..." に省略したいと考えています。
このような場合には、どのように改造すれば良いでしょうか?
ご教示いただけると幸いです。
0267nobodyさん
2007/03/05(月) 09:58:22ID:???@tests に色々入れて、試してみよう。
#!/usr/bin/perl use strict;
my @tests = (
"http://foo/bar/a.html",
"unko\nchinko\nmanko\nhttp://foo/bar/a.html",
);
for my $message (@tests) {
$message =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1<a href="$2" rel="nofollow">$2<\/a>/g;
print "message: $message\n";
}
0268nobodyさん
2007/03/05(月) 10:17:11ID:???> 質問1
> 記事の最初に '=' とかがあったとしても
「記事の最初」がどこを指しているのかよくわからないけど、
URL の直前が行頭か '=' '^' '"' 以外ならマッチする。
http://www.google.co.jp/ や
Google:http://www.google.co.jp/ なんかだと、マッチするけど
Google=http://www.google.co.jp/ や
href="http://www.google.co.jp/" だとマッチしない。
> 質問2
$2 を省略すると href="$2" の中の URL まで省略されちゃうから
自分だったら、こんな関数を定義しておいて
sub make_link {
my $url = shift;
my $text = shift || $url;
my $maxlen = shift || 80;
if (length($text) > $maxlen) {
$text = substr($text, 0, $maxlen) . '...';
}
return qq{<a href="$url" rel="nofollow">$text</a>};
}
んで /e オプション使って
$message =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1 . make_link($2)/eg;
にするかなぁ
0269266
2007/03/05(月) 10:19:40ID:???回答ありがとうございます。
いろいろいれて試してみます。
とりあえず、最初から 267 さんがいれていた2つのものは、両方ともリンクになっていました。
"=http://www.example.com/" はリンクにはならず、"=\nhttp://www.example.com/" はリンクになりました。
改行記号が入ると、別物として処理してるのかなー。
0270266
2007/03/05(月) 10:23:14ID:???> 「記事の最初」がどこを指しているのかよくわからないけど、
> URL の直前が行頭か '=' '^' '"' 以外ならマッチする。
なるほど。
納得しました。
正規表現の最初に "^" が来ると、$message の最初という意味になりますが、 "[" が入ったあとだとそれとは無関係になるんですね。
そして、([^=^\"]|^) とあるので、 = や " 以外の次に http … がマッチするということになるわけですか。
質問2についての回答は非常にためになりました。
ありがとうございました。
0271nobodyさん
2007/03/06(火) 09:39:12ID:???for($foo = int(rand(100));-z "$foo.dat";$foo = int(rand(100))){
if(-e "foo.dat"){
open($foo.dat);
中略
}
}
とやってみたら動作しませんでした。
・最初にランダムの$fooを与え
・その$foo.datが存在すれば、展開
・$foo.datが存在しない限り、ランダムで$fooを与え、存在しているかを探す
何か根本的に勘違いしてますでしょうか?
スマートなやり方など御座いましたらお教え下さい。
0272nobodyさん
2007/03/06(火) 09:53:26ID:???>・$foo.datが存在しない限り、ランダムで$fooを与え、存在しているかを探す
どうみてもそういう風に書いているようには見えないのだが。
実際には
$foo.dat が存在してサイズが0であればランダムで$foo取り直して繰り返し。
存在してサイズが0でなければなんか処理
存在しなければなにもせずに終わり
になっている。
0273nobodyさん
2007/03/06(火) 09:57:46ID:???$foo.dat が存在してサイズが0であれば(-z なら -eも自動的に成立するので)
そのファイルを開いてなんかする。そして$fooをランダムにとりなおして繰り返し。
$foo.dat が存在しないかサイズが0以外なら終了
0274nobodyさん
2007/03/06(火) 10:55:03ID:???ファイルが存在しないかサイズが1以上のファイルが存在して、終了しているだけだろ。
あと、ここはwebprog板なので排他制御を行わないと落第。
0275nobodyさん
2007/03/06(火) 14:03:48ID:???3時間 = 3 * 60 * 60 = 10800
14分 = 14 * 60 = 840
3時間14分 = 11640秒
そこでこれを作ったのですがうまく動作しません。
どう書き換えれば良いでしょうか?
# 秒数変換 Sec_trans($jikan)
sub Sec_trans {
my $rest = $_[0];
my($h,$m);
while($rest > 3600){
$rest - 3600;
$h++;
}
while($rest){
$rest - 60;
$m++;
}
sprintf("%d時間 %02d分です", $h ,$m);
}
0276nobodyさん
2007/03/06(火) 14:11:06ID:???0277nobodyさん
2007/03/06(火) 14:20:15ID:???$restはマイナスでも真じゃないかね?
localtimeは使いたくないの?
$h = int( $rest / 3600 );
$m = int( ( $rest % 3600 ) / 60 );
でいいような気もする
0278nobodyさん
2007/03/06(火) 14:40:05ID:???while($rest){
$rest - 60;
$m++;
}
つまり、この部分が無限ループになっていたわけですか。
$restはマイナス値でも真なんですね。勉強不足でした。
$jikan = 11640;
$jikan = Sec_trans($jikan);
sub Sec_trans {
my $rest = $_;
my($h,$m);
$h = int( $rest / 3600 );
$m = int(( $rest % 3600 ) / 60 );
sprintf("%d時間 %02d分です", $h,$m);
}
これを試したら、動かずに
$jikan = Sec_trans($jikan,1);
my $rest = $_[0];
と変更ところ無事動作しました。
$_と$_[0]って挙動が違うのですか?
0279nobodyさん
2007/03/06(火) 14:50:16ID:???まったく別のものです。$_[0]は配列@_の0番目の要素。
0280nobodyさん
2007/03/06(火) 14:54:16ID:???あとlocaltimeについてもぐぐってみ
先に「数値.dat」の形式のファイルを取得してからで良さそうな。。。
opendir my $dir_handle, './' or die;
my @dat_files = grep /^\d+\.dat$/, readdir <$dir_handle>;
closedir $dir_handle;
open my $file_handle, '<', $dat_files[int rand scalar @dat_files] or die;
中略
close $file_handle;
0282nobodyさん
2007/03/07(水) 15:28:55ID:JqPAOgE9foreach my $tmp (@array) {
if( $tmp eq 'P' ) { $flag = 1;last;}
}
if($flag) { print 'GA!' }
↑の文を↓のように1〜2行に収める事はできないでしょうか?
if( xxxxxxxx ) { print 'GA!' }
やりたい事は配列の中に任意のデータの有無をチェックしたいのです。
(配列の中身はデータが重複してない事が前提)
できれば、見つかった場合の要素数もわかるとありがたいです。
0283nobodyさん
2007/03/07(水) 15:54:12ID:???つgrep
>(配列の中身はデータが重複してない事が前提)
>できれば、見つかった場合の要素数もわかるとありがたいです。
要素が重複してないのなら見つかった場合の要素数は必ず1だと思うのだが...
0284nobodyさん
2007/03/07(水) 15:58:54ID:???grepという事は
if(grep(/P/, @array)) { print 'GA!' }
という感じでしょうか?
要素数というのは、配列の何番目の要素か?という事です。
0285nobodyさん
2007/03/07(水) 16:11:20ID:???同等のsubを自前で定義する方向で。
0286nobodyさん
2007/03/07(水) 16:17:35ID:???いやそれ「要素数」とは言わないし。
if (($index)=grep {$array[$_] eq 'P'} 0..$#array) { print "GA! at $index" }
0288nobodyさん
2007/03/08(木) 04:27:59ID:???$query = new CGI;
とすると、止まってしまいます。
解決方法をお願いします。
XPのIISでCGIとして動かしています。
Active Perl 5.8.7を使ってます。
0290nobodyさん
2007/03/08(木) 15:02:49ID:???記号やひらがななどを入力する人がいるので、JIS漢字以外の文字が
入力されたらエラーを表示したいのですがどうすればいいでしょうか
0291nobodyさん
2007/03/08(木) 16:05:39ID:???>>1
> 1: 自分はこういう事がしたい。
> 2: それでこんな風にやってみたが・・・
> 3: こんなエラーが出て上手く行かなかった。
1はわかったから2と3を書いてくれる?
0292nobodyさん
2007/03/08(木) 16:12:32ID:???m/[一-龠]/で試したのですがいくつかの記号が漏れてしまいます。
0293nobodyさん
2007/03/08(木) 16:54:41ID:???その順序とJISの並びは同じなのかな。
0294nobodyさん
2007/03/08(木) 16:54:42ID:???InCJKUnifiedIdeographs
とかで検索すると幸せになれる
0295nobodyさん
2007/03/09(金) 02:16:19ID:???レベルは正規表現、ハッシュ、リファレンス等テキスト加工に必要な事は出来ますが
Webからの情報入手、Webへの出力などは未経験という感じです。
そこで、せっかくperlを使ってるならとCGIを勉強しようと思い、
まずはテキスト処理がメインになりそうな2chのスレッド検索CGIでも作ろうと考えています。
素人考えでWebページからテキストを配列に渡せれば、あとはテキスト処理なんでそこそこ簡単かなと
考えていますがこれって結構難しいのでしょうか。
また、どこかに勉強になるサイト何かあったら教えてください。
0296nobodyさん
2007/03/09(金) 02:51:20ID:???>>2-3
特に perlfaq9 と CGI.pm
http://www.kt.rim.or.jp/~kbk/perl-5.8/perlfaq9.html
http://perldoc.jp/docs/modules/CGI.pm-2.89/CGI.pod
monazilla Part 5
http://pc11.2ch.net/test/read.cgi/tech/1057329161/
0297nobodyさん
2007/03/09(金) 02:52:35ID:???無理しないで辞表を出すってのも手じゃね?w
0298nobodyさん
2007/03/09(金) 14:56:13ID:???statだとアクセス日と更新日しか調べられないみたいなのでorz
0299nobodyさん
2007/03/09(金) 15:24:43ID:???0300nobodyさん
2007/03/09(金) 15:35:38ID:???0301nobodyさん
2007/03/09(金) 15:43:22ID:???記録がないのが普通なのでとりようがないはず。
ctimeで代用するのは、ctimeが更新されることは比較的少ないのでファイル
作成のときのままになってることが多いからってだけで確実ではない。
ファイルの所有者やパーミッション変えると更新だっけ。
0302nobodyさん
2007/03/09(金) 19:01:53ID:???0303nobodyさん
2007/03/09(金) 19:24:27ID:???0304nobodyさん
2007/03/09(金) 19:27:39ID:???0305nobodyさん
2007/03/09(金) 19:34:06ID:???% touch a
% stat a
File: `a'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 801h/2049d Inode: 2342931 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ matsui) Gid: ( 1000/ matsui)
Access: 2007-03-09 19:31:39.000000000 +0900
Modify: 2007-03-09 19:31:39.000000000 +0900
Change: 2007-03-09 19:31:39.000000000 +0900
% mv a b
% stat b
File: `b'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 801h/2049d Inode: 2342931 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ matsui) Gid: ( 1000/ matsui)
Access: 2007-03-09 19:31:39.000000000 +0900
Modify: 2007-03-09 19:31:39.000000000 +0900
Change: 2007-03-09 19:31:45.000000000 +0900
0306nobodyさん
2007/03/09(金) 19:36:05ID:???0307nobodyさん
2007/03/09(金) 19:42:20ID:???> Change: 2007-03-09 19:31:45.000000000 +0900
どこ見てんだよ。変ってるだろ。
0308nobodyさん
2007/03/09(金) 19:45:05ID:???0309nobodyさん
2007/03/09(金) 19:56:17ID:???cp -pでもctimeは変わるんだろうな。
0311nobodyさん
2007/03/10(土) 01:34:17ID:???Access … アクセス
Change … 変更
は分かるけど、「Modify」 って何だろう。
http://dictionary.goo.ne.jp/search.php?MT=Modify&kind=ej&from=Mozilla/Firefox
0312nobodyさん
2007/03/10(土) 02:29:19ID:???<q cite="http://www.linux.or.jp/JM/html/LDP_man-pages/man2/stat.2.html">
time_t st_atime; /* 最終アクセス時刻 */
time_t st_mtime; /* 最終修正時刻 */
time_t st_ctime; /* 最終状態変更時刻 */
</q>
0313311
2007/03/10(土) 02:50:41ID:???なるほど。
Access: 最終アクセス時刻: 最後にファイルにアクセス (開くなど) した時刻
Modify: 最終修正時刻: 最後にファイルを修正 (中身の書き換え) をした時刻
Change: 最終状態変更時刻: 最後にファイルのパーミッション等の状態を変更した時刻
いうことか…。
ありがとう。
0314nobodyさん
2007/03/10(土) 04:43:30ID:???0315nobodyさん
2007/03/10(土) 06:39:28ID:???0316nobodyさん
2007/03/10(土) 06:54:02ID:???まあどうでもいいや
0317nobodyさん
2007/03/10(土) 22:04:20ID:???このCGIを設置してみたのですが
http://dioaerts.hp.infoseek.co.jp/cgi-bin/wakuwaku.htm
http://dioaerts.hp.infoseek.co.jp/cgi-bin/wakuwaku.csv
このように検索されるものと検索されないものがあります
どうしてだか教えてください
0318nobodyさん
2007/03/10(土) 22:25:34ID:???自己解決しました吸いませんでした
0320nobodyさん
2007/03/11(日) 11:29:14ID:???これから学ぶなら何がよいのかね?
0321nobodyさん
2007/03/11(日) 12:02:16ID:SYPe8N9hPython.
0322nobodyさん
2007/03/11(日) 13:11:23ID:???初めからRubyでもいいかもしれないけど、ウェブアプリとかちょっとしたツールを作るスクリプト言語にオブジェクト指向の必要性は感じない。
それ以外の分野ならJavaとかCになるだろうし。
0323nobodyさん
2007/03/11(日) 14:05:33ID:???何をやらせても低脳
0324nobodyさん
2007/03/11(日) 15:05:02ID:???0325nobodyさん
2007/03/11(日) 16:45:41ID:???JavaやC++のような重量級言語以外に、ね。
0326nobodyさん
2007/03/11(日) 17:00:00ID:t1Paw2Qeprint "<a href=\"$ENV{'SCRIPT_NAME'}?page=$id\" target=\"_blank\">スレタイ</a>"
みたいな感じでスレタイをクリックするとそのスレッドの内容の別ページが
開くようにしたいのですが、$ENV{'SCRIPT_NAME'}?page=1 になってるところを
クリックされた場合は$ENV{'QUERY_STRING'}にpage=1として返ってくると思うのですが、
それを分解して$form{'page'}=1 となるようにして、条件で
if($form{'page'}){ printPage() ; }
としてもひっかかってくれません。。なぜかわからないでしょうか・・
0327nobodyさん
2007/03/11(日) 17:01:08ID:t1Paw2Qesub loadFormdata
{
my ($query,$pair) ;
if($ENV{'REQUEST_METHOD'} eq 'POST'){
read(STDIN,$query,$ENV{'CONTENT_LENGTH'}) ;
}
else{
$query = $ENV{'QUERY_STRING'} ;
}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair) ;
$value =~ tr/+/ /;
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg ;
$value = jcode::sjis($value) ;
$value =~ s/&/&/g ;
$value =~ s/</</g ;
$value =~ s/>/>/g ;
$value =~ s/\x0D\x0A/<br>/g ;
$value =~ tr/\t/ / ;
$form{$key} = $value ;
}
}
になっています。
0328nobodyさん
2007/03/11(日) 17:22:11ID:???0329nobodyさん
2007/03/11(日) 17:35:20ID:???PHPとかもやってると$_GET['page']ってやりたくなるよな
>>327
cgi-lib.plをrequireして&ReadParse;とかでもOK
0330nobodyさん
2007/03/11(日) 21:49:08ID:???0331nobodyさん
2007/03/12(月) 02:10:14ID:???0332nobodyさん
2007/03/12(月) 11:05:45ID:???>>326
まず$form{'page'}をprintしてみては?ちゃんと入ってる?
0334nobodyさん
2007/03/12(月) 21:46:55ID:???どんなデメリットあるんだろう・・
0335nobodyさん
2007/03/12(月) 22:41:31ID:???古いコードの保守ならともかく、これから新規で書くんならCGI.pmがオススメ
0336nobodyさん
2007/03/12(月) 23:33:07ID:???0337nobodyさん
2007/03/12(月) 23:59:28ID:???0338nobodyさん
2007/03/13(火) 00:12:24ID:???0339nobodyさん
2007/03/13(火) 00:12:38ID:???CGI::Minimalあたり使ってろよ
0340nobodyさん
2007/03/13(火) 00:37:46ID:7SHHDDju色々調べたけどお手上げ…
0341nobodyさん
2007/03/13(火) 00:43:35ID:???0342nobodyさん
2007/03/13(火) 00:59:27ID:???単純なテーブルならデータにdel_flgとか持たせとくとか
別にテーブル作ってIDとdel_flgで状態を管理とか
0343nobodyさん
2007/03/13(火) 01:21:54ID:7SHHDDjupackage Item;
__PACKAGE__->columns(Primary => qw/id/);
__PACKAGE__->columns(Others => qw/name maker note del_flag/);
__PACKAGE__->has_many(groups => 'Group');
package Group;
__PACKAGE__->columns(Primary => qw/id/)
__PACKAGE__->columns(Others => qw/name del_flag/);
・・・
CDBIでリレーションしてる他のテーブル(例えばGroup)
にもdef_flagのようなフラグをつけていて、
@data = Item->search_like(name => 'pc');
みたいな時に、Groupが論理削除されている場合は拾って来ないようにして、
Item->groups->name
には生きているデータだけ持ってきたいのだけど…
0344nobodyさん
2007/03/13(火) 01:27:58ID:7SHHDDjupackage Group;
__PACKAGE__->columns(Primary => qw/id/)
__PACKAGE__->columns(Others => qw/name item del_flag/);
・・・
でした。因みに出力はTTです。
0345nobodyさん
2007/03/13(火) 01:31:58ID:7SHHDDjuとかだと、Itemの削除したものはあがってこないが、
Groupの方は関係ないから普通に拾ってきてしまうのよね…
>>342 <早速のレスありがとうございます。
0346nobodyさん
2007/03/13(火) 04:25:58ID:???0347nobodyさん
2007/03/13(火) 07:08:26ID:???0348nobodyさん
2007/03/13(火) 10:54:37ID:???0349nobodyさん
2007/03/13(火) 12:59:08ID:RaCGoxpM$in{'name'}ってのを$in{'$rand'}ってやって乱数にしたいんだけど
どうやってやればいいんでしょうか?
ちなみに$randは乱数です。
0350nobodyさん
2007/03/13(火) 13:14:50ID:???$in{$rand} = 'hogehoge';
0351nobodyさん
2007/03/13(火) 13:20:42ID:RaCGoxpM動きません・・・・
0352nobodyさん
2007/03/13(火) 13:26:14ID:RaCGoxpM<input type=text name="OMbqcVSSOZkugP167bljsl3zHt5uVk" size=28 value="">
書き込みのフォームがこんな感じになっていて、name"$rand"ってなっています。
ですが$in{'name'}を$in{'$rand'}にしても書込みをさせてくれません・・・。
どうすればできますでしょうか?
0353nobodyさん
2007/03/13(火) 13:28:17ID:???0354nobodyさん
2007/03/13(火) 13:30:12ID:???$randにしかるべき文字列が設定されているのが前提だが。
0355nobodyさん
2007/03/13(火) 13:34:38ID:RaCGoxpMですが$in{$rand}ってやっても全然書き込み出来ません・・・。
0356nobodyさん
2007/03/13(火) 13:41:49ID:???0357nobodyさん
2007/03/13(火) 13:42:19ID:RaCGoxpM0358nobodyさん
2007/03/13(火) 13:43:39ID:???0359nobodyさん
2007/03/13(火) 13:46:07ID:RaCGoxpM0360nobodyさん
2007/03/13(火) 14:05:26ID:???たとえば、$i に 1234567890 が入っていたら、 1A234A567A890 とか、1 234 567 890 といった感じです
いい方法あったら教えてもらえませんか?
0361nobodyさん
2007/03/13(火) 14:05:53ID:???コーディングでエラーが出たら質問するといい
■ このスレッドは過去ログ倉庫に格納されています