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-04-05

[][][]ネストされた括弧を使う時の番号付き変数の順番は 17:39 ネストされた括弧を使う時の番号付き変数の順番は - ishiducaの日記 を含むブックマーク はてなブックマーク - ネストされた括弧を使う時の番号付き変数の順番は - ishiducaの日記 ネストされた括弧を使う時の番号付き変数の順番は - ishiducaの日記 のブックマークコメント

正規表現では、括弧 "()" と番号付き変数 "$1","$2",... のセットが便利ですね。

上手に使うのは難しいんですけど、入れ子に(ネスト)された場合の番号の振り方くらい、覚えておきたいので試してみました。

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

$_ = 'abc def ghi jkl';
my $reg = '([^\s]+)\s(([^\s]+)\s([^\s]+))\s(.+)';
/$reg/ and print join "\n", $1, $2, $3, $4, $5;

exit 0;

結果

abc
def ghi
def
ghi
jkl

括弧と順番だけを端折って書くと

(1)((3)(4))(5)

2番目が見当たりませんが (1)と(5)に挟まれた括弧--(3)と(4)を囲んだ括弧--がそれ。

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