【先着1,000名様!】1,000円分をプレゼント!

perlで書かれたとある掲示板に機能追加すべくソースをいじってます。
意味のわからないコードがあるので、教えて下さい。

$skin =~ s/(name="s_word")/$1 value="$in{s_word}"

とか、

$hogehoge = $1;

のような感じで出てくる、$1ってどういう変数なのでしょうか?
どういったときに用いられるのでしょう?

また、=~ というのは、どういう意味なのでしょうか?

どなたか、ご教授下さいませ。
よろしくお願い致します。

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

A 回答 (4件)

> $hogehoge = $1; の場合の、$1は違う意味合いになるのでしょうか?



この $1 も同じものです。
よく似たものに \1 という後方参照用の特殊変数があります。働きは $1 と全く同じです。
たとえば、HTMLから「前後を対のタグで挟まれた部分」を探すとき、
<.+?>.*?</.+?>
と書いてしまうと、「<LI>ABC</UL>」なんていうのまでマッチしてしまいますよね。
そうではなく、「ULで始まったらULで閉じている部分」をマッチさせたいときは、
<(.+?)>.*?</\1>
と書きます。そうすると「<UL><LI>ABC</UL>」というように、正しい対になっている部分にのみマッチします。
最初の括弧の部分で見つけたものが、\1 に格納されているからです。
ところが、\1 や \2 は、その寿命(値保持)はパターンの中だけです。たとえば、見つけた後にその見つけたタグは何だったのか?処理の中で使いたいときがあり、そんなとき使えるのが $1 や $2 です。こちらは \1 や \2 と働きは同じで、その寿命が長いものです。具体的には、ブロック{}の中、または次に他の値が入れられるまで値を保持しています。

if (/<(.+?)>(.*?)</$1>/) {
print "$1 タグで挟まれた部分は「$2」です。"
}

ちなみに、後方参照用の特殊変数には、
$+
$&
$`
$'
などもあります。
    • good
    • 1
この回答へのお礼

\1も$1も、その前に存在している( )内の値が格納されるという意味ですね。
つまり、$hogehoge = $1;の前に存在している( )内に何が記述されているか、そしてそこにどんな値が格納されてくるのかを考えれば、$hogehoge変数に、何が代入されるのかを想像できるということですね。

奥が深いようですが、このあたりが自由に使いこなせると、かなりperlをモノにできそうな気がします。
いろいろなパターンのテストコードを書いてみて、もっと理解を深めてみたいと思います。
取りあえず、引っかかっている部分は、解消できました。
どうも、ありがとうございました!

お礼日時:2005/07/16 02:33

>$hogehoge = $1; の場合の、$1は違う意味合いになるのでしょうか?


同じ意味合いです。
この文の前にある何らかの正規表現のマッチングを行ったグループを
その正規表現のマッチングをさせた式よりあとでも(次のマッチングとかで更新されるまで)使うことができます。
    • good
    • 0
この回答へのお礼

先の方の回答で、$1は、その前に存在している( )内の値が格納されるという意味だとわかりました。
つまり、$hogehoge = $1;の前に存在している( )内に何が記述されているか、そしてそこにどんな値が格納されてくるのかを考えれば、$hogehoge変数に、何が代入されるのかを想像できるということですよね。
ありがとうございました。

お礼日時:2005/07/16 02:35

$1 は後方参照用の特殊変数です。


括弧つきのパターンマッチを実行した後で、マッチした文字列を参照できます。
/Yahoo|Google/
と書くと、「Yahoo」または「Google」という文字列を探します。
これに括弧を付けて、
s/(Yahoo|Google)/$1 Japan/g
と書くと、「Yahoo」を「Yahoo Japan」に、「Google」を「Google Japan」に変換します。つまり「見つけたのは何だったのか?」を後から知る(参照する)ことができます。(後方参照)
後方参照せずに、普通の括弧の働き、つまり単にグループ化させたいだけなら
(?:~)
と書きます。

=~ は、デフォルトではパターンマッチングは変数 $_ に対して行いますが、それ以外の変数に対して行いたいときに、結びつけるための演算子です。
=~ の真偽が逆になるのが !~ です。

これらはperlの基本ともいえるので、しっかり習得されてから進めることをおすすめします。
    • good
    • 0
この回答へのお礼

ありがとうございます。
$1 は後方参照用の特殊変数というのはご説明で理解できてきた感じです。
しかし、$hogehoge = $1; の表現がわかりません。
$hogehoge = $1; の場合の、$1は違う意味合いになるのでしょうか?

お礼日時:2005/07/16 01:14

この辺で↓



参考URL:http://www.tohoho-web.com/wwwperl.htm
    • good
    • 0
この回答へのお礼

$1 は、まだ理解不透明ですが、
=~ は、理解できた感じです。
ありがとうございました。

お礼日時:2005/07/16 01:11

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

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

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

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

Qfetchrow_arrayとfetchrow_hashrefの使い方

Jやまとです。
PerlからSELECT文を実行して結果の行の値を取得する単純なスクリプトを作成しています。
(1)fetchrow_array使用
(2)fetchrow_hashref使用
以上2通りの方法で試したのですが、(2)がInternal Server Errorになります。
原因が全く分かりません。
分かる方いらしゃいましたら、ご教授願います。
OS:TurboLinux6.2
DB:Oracle8i
Apache,PerlはTurboLinux6.2に入っているものをそのまま使用
以下、ソースを記載します。
---------------
(1)fetchrow_arrayを使用して行の値を取得(こっちは動く)
$dbh = DBI->connect($ds, $user, $pass) || &dbErr("Database can't connect." . $DBI::errstr);
$sql = "SELECT SYSDATE FROM DUAL \n";
$sth = $dbh->prepare( $sql );
$sth->execute or die "Cannot execute. " . $sth->errstr();
$cnt1 =1;
while (@row = $sth->fetchrow_array()) {
@{$get_date[$cnt1]} = @row;
$cnt1++;
}
---------------
(2)fetchrow_hashrefを使用して行の値を取得(こっちが動かない)
$dbh = DBI->connect($ds, $user, $pass) || &dbErr("Database can't connect." . $DBI::errstr);
$query = qq{
SELECT SYSDATE FROM DUAL
};
$sth = dbh->prepare($query);
$sth->execute(); # 実行
if($sth->rows() != 1){ # 該当する行数
# エラー処理
}
$rhash = $sth->fetchrow_hashref();
%hash = {%{$rhash}};
$sth->finish();
$get_date = $hash{SYSDATE};
---------------
(2)実行時のerror_log
Can't locate object method "prepare" via package "dbh" at /u01/ora1/www/htdocs/hoge.cgi line 30.
Premature end of script headers: /u01/ora1/www/htdocs/hoge.cgi
---------------
(本文長くてすみません)

Jやまとです。
PerlからSELECT文を実行して結果の行の値を取得する単純なスクリプトを作成しています。
(1)fetchrow_array使用
(2)fetchrow_hashref使用
以上2通りの方法で試したのですが、(2)がInternal Server Errorになります。
原因が全く分かりません。
分かる方いらしゃいましたら、ご教授願います。
OS:TurboLinux6.2
DB:Oracle8i
Apache,PerlはTurboLinux6.2に入っているものをそのまま使用
以下、ソースを記載します。
---------------
(1)fetchrow_arrayを使用して行の値を取得(こっちは...続きを読む

Aベストアンサー

rowsメソッドと同じく、executeが正しく処理レコード数を返すのは、非select文を実行した場合のみです。
select文の場合、rowsもexecuteも0行と認識するDBDが多いです。
で、これはselect文に限らずですが、処理レコード数が0の場合は、0自体ではなく「0E0」を返します。
これは、0を返すと、実行エラー時の戻り値undefと同様、
if ($sth->execute) {} で失敗したのと同じことになってしまうためです。
select文の行数は、fetchしながら行数をカウントするか、取り込んだ、配列、ハッシュの数をカウントするのが一般的な方法ですね。fetchする前に取得する方法はわかりません。

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

QHTMLフォームのSELECTの幅を一定にするためには?

HTMLフォームのSELECTの幅を一定にするためにはどのようにすれば
いいのでしょうか?

CSS等で設定できるとありがたいのですが、やり方がわかりません。

Aベストアンサー

<select style="width: 200px">

QPerlで環境変数を設定するには

あるPathを環境変数として設定したい場合、
例)TNS_ADMIN=D:\Test\exe

たとえばMS-DOSなら、
set TNS_ADMIN=D:\Test\exe
と設定しますよね。

これと同じことをPerlでどうやればいいのかというのが質問です。

ENVモジュールを使って、
$ENV{TNS_ADMIN}=D:\Test\exe
としてみたものの、Perlを実行した後に確認してみるとセットされていないようでした。
(確認方法はPerlを実行したDOSプロンプトにて"set"を実行)

よろしくお願いします。

Aベストアンサー

>>破棄された後に確認しても、わかりません。
>どうにかその環境変数がセットされていることを確認する方法ってないのでしょうか?

perlで子プロセスを起動すれば確認できます。

例えば、NT系のOSであれば...

次のスクリプトを用意。
#!c:\perl\bin\perl.exe
$ENV{"TNS_ADMIN"}="D:\\Test\\exe";
system("cmd");

それを実行すると、コマンドプロセッサが表示されるので、
set[return]
すれば、子プロセスの環境変数が確認できます。
確認後、exit[return]すると、子プロセスが終了するので、
親プロセスたるperlも終了する。

Qcgiとplとpm

掲示板ソースをダウンロードするとplやpmという拡張子のものがありました。中身はPerlでした。
拡張子の使い分けを教えてください。

適当に4つのルールを書いてみましたので、間違っていたり、追加するルールがありましたから教えてください。

1 ブラウザがそれ自身にアクセスし、ブラウザのアドレスバーに表示させるならcgiにするべき。

2 Perlのpackageの機能を使うなら、パッケージファイルはplかpmでなくてはならない。

3 Perlのrequireの機能を使うなら、その外部ファイルはplでなくてはいけない。

4 Perlのuseの機能を使うなら、その外部ファイルはpmでなくてはならない。

Aベストアンサー

基本的に拡張子は、あっても無くてもなんでもOKです。ただ、モジュールには.pmをつけなければなりません。
また、webサーバによってCGIとして使える拡張子に制限がある場合があります。

1.について
言語として、特に拡張子を.cgiにしなければならないというのはありません。.plでも.doでも.hoge
でも基本的には大丈夫ですが、大抵運用するwebサーバによって使える拡張子が制限されています。.cgiしかダメなサーバとか。

2.について
そのような制限はありません。拡張子は何でもOKです。
ただ、前述の通りwebサーバによって拡張子の制限がかかっている場合はCGIとしては実行できません。

3.について
そのような制限はありません。拡張子は何でもOKです。

4.について
その通りです。use関数の対象になる外部ファイルは.pmでなければなりません。

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 $_; ##出力してみる。
}
}

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

Qファイルの行数取得

超初心者です。

いま、表計算的なスクリプトを記述しています。

あるファイルの行数を取得する関数ってあるんでしょうか?

ファイルに記述されている数値を足したり引いたりするのですが、forを使っての計算の際にファイルの行数が必要となりました。

Aベストアンサー

Perlにですね。ないはずです。
行数とはファイルに書かれた改行文字の個数ということなので
実際にファイルを全て読み込まないと行数はわかりません。
以下のように色々な方法があると思います

#### 単純な例
$a = 0;
open FD, "<file.txt" || die $!;
while (<FD>) {
$a++;
}
close FD;
print "行数:$a\n";

### 少しマニアックな方法
open FD, "<file.txt" || die $!;
@a = <FD>;
close FD;
print "行数:" . ($#a + 1) + "\n";


### 反則的方法(外部コマンド) ... UNIXの場合
print "行数:" . `wc -l file.txt` . "\n";

Qコンソール出力をテキストに出力する方法(コンソール出力は残しつつ)

【質問】
 Perl内部で実行される実行ファイル(.exe)のコンソール出力(STDOUT,STDERR)をテキストファイルに出力したい。(Perlのコンソール出力も含む。) ※コンソール出力は残しつつ。

(コマンドプロンプトの)パイプとリダイレクトを使用して上手くいくかと思ったのですが、標準出力と標準エラーとでは標準エラーが先に出力されてしまい、本来出力される順番で出力されない。(標準出力はバッファにたまるため??)

何かいい方法はありませんでしょうか?

【環境】
 Windows2000
 Active Perl 5.8.8

Aベストアンサー

CPANモジュールの File::TeeとかIO::Teeを使うというのはどうでしょうか?

File::Tee - replicate data sent to a Perl stream - search.cpan.org
http://search.cpan.org/~salva/File-Tee-0.03/lib/File/Tee.pm

use File::Tee qw(tee);

# simple usage:
tee(STDOUT, '>', 'stdout.txt');

print "hello world\n";

IO::Tee - Multiplex output to multiple output handles - search.cpan.org
http://search.cpan.org/~kenshan/IO-Tee-0.64/Tee.pm

use IO::Tee;
use IO::File;

my $tee = new IO::Tee(\*STDOUT,
new IO::File(">tt1.out"), ">tt2.out");

print join(' ', $tee->handles), "\n";

for (1..10) { print $tee $_, "\n" }
for (1..10) { $tee->print($_, "\n") }
$tee->flush;

CPANモジュールの File::TeeとかIO::Teeを使うというのはどうでしょうか?

File::Tee - replicate data sent to a Perl stream - search.cpan.org
http://search.cpan.org/~salva/File-Tee-0.03/lib/File/Tee.pm

use File::Tee qw(tee);

# simple usage:
tee(STDOUT, '>', 'stdout.txt');

print "hello world\n";

IO::Tee - Multiplex output to multiple output handles - search.cpan.org
http://search.cpan.org/~kenshan/IO-Tee-0.64/Tee.pm

use IO::Tee;
use IO::File;

...続きを読む

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Qバッチ処理でファイルの中身を変数に入れるやり方

あるファイルの中には1行の文字列があります。
このファイルをバッチで読み取り、変数に設定したいです。

例:
test.txt
abcacbacbacbacbacbacbacbacb

test,bat
set DATA=[test.txtを読み込んだ値]

よろしくお願い致します。

Aベストアンサー

これですね。

参考URL:http://www.upken.jp/kb/dqvgHNRUxwFDkmtoqEwfXHUjDrevNv.html


このカテゴリの人気Q&Aランキング