ishiducaの日記 このページをアンテナに追加 RSSフィード

2009-05-15

[][]正規表現(マッチング)で変数を使う時は「'」を使う 21:24 正規表現(マッチング)で変数を使う時は「'」を使う - ishiducaの日記 を含むブックマーク はてなブックマーク - 正規表現(マッチング)で変数を使う時は「'」を使う - ishiducaの日記 正規表現(マッチング)で変数を使う時は「'」を使う - ishiducaの日記 のブックマークコメント

複雑な条件でマッチングを行うと一行が長くなるので、変数を使う。

例えば、日付(YYYYMMDD)を使用したファイル名で、拡張子が「diary」もしくは「travel」、「shopping」のもので絞り込む場合、こんな感じで書いてみる

1: #!/usr/bin/perl -wnl
2: use strict;
3: BEGIN {
4:     @ARGV or @ARGV = <*>;
5:     @ARGV = grep{ -T and /^20[0-9]{6}\.(diary|travel|shopping)$/i }@ARGV;
6:     @ARGV or warn "not found files.\n" and exit 255;
7: }
8: # データ処理の部分

複雑な条件であればあるほど、5行目が長くなるので、正規表現の部分に変数を使って、書く。

    my $reg = '^20[0-9]{6}\.(diary|travel|shopping)$';
    @ARGV = qrep{ -T and /$reg/i }@ARGV;

「'」を「"」で囲むとエラーを吐く

    my $reg = "^20[0-9]{6}\.(diary|travel|shopping)$";
    @ARGV = qrep{ -T and /$reg/i }@ARGV;

実行結果

Final $ should be \$ or $name at sample_script line 5, within string
syntax error at sample_script line 5, near "= "^20[0-9]{6}\.(diary|travel|shopping)$""
BEGIN not safe after errors--compilation aborted at sample_script line .

なので、「"」で囲まず「'」を使う。あるいは「$」を「\$」でエスケープすると使える。my $reg = "^20[0-9]{6}\.(diary|travel|shopping)\$";

理由がない限り「'」を使った方が良さそう。


追記(2009.05.20)

エラーを吐いた箇所は別にあったようです(id:kitsさんがブックマークでご指摘くださいました。感謝)。

$" という定義済み変数があるため、文字列を括るための末尾の " が無くて文法エラーとなっているのであり、正規表現は関係無さそう。

引っかかったところを箇条書きにすると

  • ダブルクォート「"」で括ると、変数展開する
  • 変数展開するので、最後の「$"」が配列を扱う特殊変数(下記参照)と解釈された(そのため、最後に「"」が足りないと怒られてる)
$"ダブルクォートで囲んだ配列の各要素の間に自動的に挿入される文字を保持する。デフォルトでスペース
$'マッチしたレコード中で最後のマッチの末尾にくる部分を保持する

ダブルクォートを使った場合変数展開をするので、変数展開を意図しない場合は、シングルクォートを使った方がいいのはかわらないんだけど(強がり)。

この記事のタイトルからして訂正した方がいいかな。

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090515

2009-04-14

[][][]量指定子{m,n}を使って文字数制限のテストをしたけど、うまくいかなかったのでメモ 21:52 量指定子{m,n}を使って文字数制限のテストをしたけど、うまくいかなかったのでメモ - ishiducaの日記 を含むブックマーク はてなブックマーク - 量指定子{m,n}を使って文字数制限のテストをしたけど、うまくいかなかったのでメモ - ishiducaの日記 量指定子{m,n}を使って文字数制限のテストをしたけど、うまくいかなかったのでメモ - ishiducaの日記 のブックマークコメント

次の二つの条件にマッチしたかをテストする

  • 半角英数字とアンダーバーのみで構成された文字列
  • 4文字以上、6文字以下

まず、失敗例

#!/usr/bin/perl -wl
use strict;

$_ = 'ishiduca';
/\w{4,6}/ and print "match" or print "un match";   # 不正解

次、成功

#!/usr/bin/perl -wl
use strict;

$_ = 'ishiduca';
/^\w{4,6}$/ and print "match" or print "un match"; # 正解

結構悩んだ

ishiducaishiduca2009/04/15 11:52できるだけワンライナーで書きたいので書き直してみる
perl -wl -e 'print "ishiduca" =~ /^\w{4,6}$/ ? "match" : "un match";'

MelMel2012/08/19 20:22At last! Soemnoe with real expertise gives us the answer. Thanks!

tvtsctdndeutvtsctdndeu2012/08/20 18:01OdbAUs <a href="http://hsbgbhuyouat.com/">hsbgbhuyouat</a>

rikkebarptprikkebarptp2012/08/22 14:19ReAqaB <a href="http://xmpftsqlppmr.com/">xmpftsqlppmr</a>

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090414

2009-03-25

[][][]cpanからIOモジュールをインストールした 20:11 cpanからIOモジュールをインストールした - ishiducaの日記 を含むブックマーク はてなブックマーク - cpanからIOモジュールをインストールした - ishiducaの日記 cpanからIOモジュールをインストールした - ishiducaの日記 のブックマークコメント

a2ps を macport からインストールして、テキストファイルをpsファイルに変換しようとしたところ、エラーを吐いて失敗した。(中略)。とりあえず諦めて、LWP::Simpleモジュールを使うスクリプトを書いていたんだけど、「Can't locate LWP.pm in @INC (@INC ...」と、モジュールがないってメッセージを吐いて終わってしまった。他のモジュールをいくつか試してみたけど、ダメっぽい。以前、miyagawaさんのブログでmacでcpanモジュールをインストールしたことのあるleopardマシンのperlモジュールがだめになるとか言うエントリーがあったのを思い出して、IOモジュールをインストールしたので、その手順のメモ。

  • cpanからIOモジュール(IO-1.2301.tar.gz)をダウンロード
$ wget http://search.cpan.org/CPAN/authors/id/G/GB/GBARR/IO-1.2301.tar.gz
  • tarコマンドでtar.gzファイルを解凍
$ tar xzvf IO*.tar.gz
  • cdコマンドで展開したディレクトリへ
cd IO*
  • make してインストール
perl Makefile.PL
make
su
make install

こんな感じ。miyagawaさんのブログだと su じゃなくて sudo を使っていたけど、他のモジュールをインストールしようとしたら、「warning: You don't have permissions to install into...」とエラーを吐くので、ルート権限をもつ su してインストールしたらうまくいったっぽい。

他にもインストールした方がいいモジュールがあるようです(以下参照)

これから、暇を見つけて上書きインストールをやらなくちゃ、やれやれ。。。

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090325

2008-11-06

[][][]localを使おうとして怒られた 16:42 localを使おうとして怒られた - ishiducaの日記 を含むブックマーク はてなブックマーク - localを使おうとして怒られた - ishiducaの日記 localを使おうとして怒られた - ishiducaの日記 のブックマークコメント

use strict;
my $str = 'GROBAL';
&PUT();
sub PUT{
    local $str = 'local';
    print $str."¥n";
}
print $str; 

ってやったら、"Can't localize lexical variable $str at - line 5." って怒られた。my を使っちゃいけないらしい。んな訳で

str = 'GROBAL';
&example();
sub example{
    local $str = 'local';
    print $str."¥n";
}
print $str;

結果

local
GROBAL

成功


追記(2009.05.10)

「local」はサブルーチンの中で、グローバル変数の中身を一時的にどこかへ移動して、その代わりに別の値を使う。サブルーチンから抜けると、元の値に戻すものでした。(今更...)

なので、この書き方の方がいいんだろうね

#!/usr/bin/perl -wl
use strict;
our $str ='GROBAL'; # our宣言で、グローバル変数に設定
&example();
sub example{
    local $str = 'local'; # local宣言して、グローバル変数の値を一時的に退避
    print $str;
}    
print $str;
exit 0;
トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20081106

2008-11-05

[][]ブロック内でmy宣言した変数(レキシカル変数)のスコープ(有効範囲) その1 16:20 ブロック内でmy宣言した変数(レキシカル変数)のスコープ(有効範囲) その1 - ishiducaの日記 を含むブックマーク はてなブックマーク - ブロック内でmy宣言した変数(レキシカル変数)のスコープ(有効範囲) その1 - ishiducaの日記 ブロック内でmy宣言した変数(レキシカル変数)のスコープ(有効範囲) その1 - ishiducaの日記 のブックマークコメント

何気にやってしまった

> perl
use strict;
use warnings;

my $value = 100;
if( $value < 100 ){
	my $q = 'under';
} else {
	my $q = 'over';
}
print $q;

結果

Global symbol "$q" requires explicit name at -line 8.
Excutaion of - aborted due to compilation errors.

実際は、こんな簡単なコードじゃないけど、if文を使ってやっちゃいました。

javascript だと、ブロックレベルで変数のスコープはされないんだけど、perl では ブロックレベルでmy宣言された変数は、そのブロックレベルでしかスコープされないんでした。初歩的なミスでした。

んな訳で、やりなおし

> perl
use strict;
use warnings;

my $value = 100;
my $q = undef;
if( $value < 100 ){
	$q = 'under';
} else {
	$q = 'over';
}
print $q;

結果

over

NahirNahir2012/11/03 14:58This info is the cat's paamjas!

tuhpgpjnptotuhpgpjnpto2012/11/04 06:03ipBx7r <a href="http://tcdbnhmccvro.com/">tcdbnhmccvro</a>

itgxxpevitgxxpev2012/11/05 14:12qgNhrv , [url=http://jzufdxvlcclk.com/]jzufdxvlcclk[/url], [link=http://cbahgieqjeii.com/]cbahgieqjeii[/link], http://qbyfnwppxfgj.com/

itliymaitliyma2012/11/07 22:38Iii9OX <a href="http://oeuptkhymuca.com/">oeuptkhymuca</a>

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20081105