2006年12月22日 19:00 [Edit]

{perl,ruby} -nle 'print if /start/../end/'

camel

アルファギークでも知らなかったというのは、不思議でもあり当然のようでもあり。

naoyaグループ - naoyaの日記 - if /regexp/../regexp/
Perl で正規表現を .. すると、その間に含まれる文字列という意味でマッチさせられる。 % w3m -dump_source http://www.yahoo.com/ | perl -nle 'print if /^<style/../<\/style>/' とすると

これ、実に由緒正しい使い方で、たしかまだperlがhashすらサポートしていない頃からあったと記憶しています。なにしろsed/awkが起源ですから。

NAME operator - search.cpan.org
In scalar context, ".." returns a boolean value. The operator is bistable, like a flip-flop, and emulates the line-range (comma) operator of sed, awk, and various editors. Each ".." operator maintains its own boolean state.

もちろん、日本語のドキュメントもあります。

The Perl5 Manual - 範囲演算子
スカラコンテキストで使われたときには、".." はブール値を返します。この演 算子は、フリップフロップのように 2 値安定で、sed や awk や多くのエディタ での行範囲 (コンマ) 演算子をエミュレートするものとなります。

しかしこれを見て「こんなことまでできるのか、さすが変態言語」と言っているあなた、甘いです。以下をご覧下さい。

% GET http://www.yahoo.com/ | ruby -nle 'print if /^<style/../<\/style>/'
<style type="text/css">
a{color:#16387c;}
a:link,a:visited{text-decoration:none;}
a:hover{text-decoration:underline;}
<style type="text/css">
a{color:#16387c;}
a:link,a:visited{text-decoration:none;}
a:hover{text-decoration:underline;}
</style>
<style type="text/css" media="all">
#p{width:310px;}
form{margin:0;}
</style>
Rubyリファレンスマニュアル - 演算子式
条件式として範囲式が用いられた場合には、式1が真になるま では偽を返し、その後は式2が真を返すまでは真を返します。式2が 真になれば状態は偽に戻ります。..は式1が真になっ た時にすぐに式2を評価し(awkのように)、 ... は次の 評価まで式2を評価しません(sedのように)。

これを見てもまだ信じられない人は、以下を実行していましょう。

% ruby -e 'require "open-uri"; open(ARGV.shift).each{|l| puts l if (l=~/^<style/i)..(l=~/\/style>/i)}' http://www.yahoo.com/

「レンジでチン」ならぬ「レンジでちょんちょん(..)」ないし「ちょんちょんちょん(...)」って、手軽で便利ですが、こんなところでも使われているというお話でした。

Dan the Man with Too Many Languages to Speak


この記事へのトラックバックURL

この記事へのトラックバック
naoyaグループ - naoyaの日記 - if /regexp/../regexp/ {perl,ruby} -nle ’print if /start/../end/’ に書かれているスクリプトをWindowsXPで試した。シングルクォート(’)をダブルクォート(”)に置き換え、ダブルクォート(”)には直前に円記号(¥)を挿入してエスケー...
Winで試してみた。【Courantの日記】at 2006年12月23日 05:26
この記事へのコメント
http://d.hatena.ne.jp/raki321/
貴方なら、私がなんであるか、分かるでしょう?
コメントとかあればホントお願いします。
ブログ内容を少しソフト化してみましたので。
Posted by モーリス・G・茶茶 at 2006年12月23日 08:47
Perl5から入った世代は知らないんでしょうね。
今となっては、あくまでワンライナー用であってobsoleteと思った方がいいですが。
Posted by 774 at 2006年12月23日 07:59
fooさん、
あ、ほんとだ。直しました。
#おかしいな。ちゃんとペーストしたはずなのだが
Dan the Typo Generator
Posted by at 2006年12月23日 00:53
# そのまま書いてよかったのか…。

<, > に読み替えてくださいまし。
Posted by foo at 2006年12月23日 00:07
ruby -nle 'print if /^&lt;style/../&gt;\/style&gt;/'
ではなくて
ruby -nle 'print if /^&lt;style/../&lt;\/style&gt;/'
ではないですかね。
Posted by foo at 2006年12月23日 00:04
「ま」さん、
失礼。自分のそれはOKでしたが、引用部分がentitityになってませんでした。
courantさん、
現在はちゃんと直っていると思います。手元のOpera Macで確認した限りではOKでした。
Dan the Typo Generator
Posted by at 2006年12月22日 21:51
∧_∧∩ 先生、IE7、OPERA9.10だと表示がおかしくなるであります。
http://download.sarabande.info/Image00094.jpg
Posted by courant at 2006年12月22日 21:49
<styleのあたりを&lt;とか&gt;やってくれないと読めないです。
Posted by ま at 2006年12月22日 21:14