« 2010年5月 | トップページ | 2010年7月 »

2010年6月

2010年6月30日 (水)

通常文字をメタ文字(metacharacter)化する逆エスケープ(escape)がある

通常文字をメタ文字(metacharacter)化する逆エスケープ(escape)がある

Time-stamp: "Mon May 03 16:20:38 JST 2010"

曖昧な文字列の指定方法に正規表現(regular expression)がある。regular を指定すれば一字たりとも違わないものを指定したことになる。これを [Rr]egularとすると頭文字の大文字・小文字を問わない指定になる。ここで 使われている角カッコ[ ]をメタ文字(metacharacter、超文字、文章を記述 するための文字の役割を超えて特別な意味を持たせた文字)という。メタ文 字に対して字面どおりの役割をする文字を通常文字と呼ぶことにする。

どんな文字をメタ文字としたらよいだろうか。それには実際の文章における 使用頻度が少ないものから選ぶのがよい。アルファベットや数字より記号類 のほうが使われない。そのため先ず記号類をメタ文字に割り当てる。

メタ文字に与えた特別な意味付けを無効にして字面どうりを指定したいとき にはそのメタ文字の直前にエスケープ文字(これもメタ文字になる)を置く。 エスケープ文字としてはバックスラッシュを使う。バックスラッシュは機械 式タイプライターには無いものでコンピュータの世界で使われはじめた記号 である。それが通常の文章に現われることはない。

複雑な文字列パターンを指定しやすいように正規表現は次第に進化してお り、それに連れて記号類だけを使ったメタ文字では不足するようになってい る。現在ではアルファベットや数字などの通常文字もメタ文字として使われ る。そうなると通常文字をメタ文字化する必要がある。それにはメタ文字の 通常文字化と同じように通常文字の直前にバックスラッシュを置いて逆エス ケープする。

日本ではバックスラッシュに通貨単位の円記号を割り当てる。他の文字に置 き換えても不都合の起こらない文字だからがその理由である。なお「\」(エ スケープ文字としてのバックスラッシュ)はメタキャラクタであるからバッ クスラッシュ自身を表すにはエスケープして「\\」とする。

ところで正規表現のヘルプをmeadowから参照するには「C-h i」でinfoを出 してRegexps(regular expressions)でヘルプを参照する。meadowのヘルプは meadow/info/ディレクトリに収められている。日本語化せず英語のままなの で読むことはない。もっぱら解説本に頼っている。

viではpatternをキーワードにして「:help pattern」とするとヘルプが読め る。詳しいことはvim/doc/pattern.txtに書かれている。viは解説本が少な いのでヘルプを日本語化している。ヘルプの日本語化は「名無しのvim使 い」さんのページを参考にする。

viとmeadowでは正規表現関連のキーワードが違う。ヘルプのキーワードと して何を指定すればよいのかと探しまわってその違いに気付いた。

英語ヘルプはそのままとし~/vimfiles/docや~/vimfiles/syntaxに日本語ヘ ルプファイルを置く。日本語ヘルプを先に表示するように設定をする。デ フォルトのヘルプを置き換えることはしない。

viの編集コマンドはテキスト処理言語であるsedのコマンドに似ている。テ キストファイルの加工に特化したsedを真似ているため検索置換などが少な いキー操作で簡単にできる特長がある。

viの正規表現検索では「.」(改行文字以外の任意の一文字)、「*」(直前に ある一文字の任意の個数(0個も含む)の並び)、「^」(行の先頭)、「$」(行 の末尾)、「[ ]」(角括弧内(リスト)のどれか一文字)、「[^ ]」(リスト中 にない任意の一文字)などをメタキャラクタ(超文字、文章を記述するための 記号文字の役割を超えて特別な機能を持たせた文字)として使う。

たとえば「^a」は行の先頭にある文字「a」を表す。カレット記号(^)とアル ファベット小文字のaの並びではない。単純に文字列「^a」を探すのであれ ばカレットがメタキャラクタでないことを示す必要がある。それにはバック スラッシュを前置して「\^a」とする。

バックスラッシュでメタキャラクタをエスケープして通常文字化することが 殆どであるが、ときには通常文字をエスケープしてメタキャラクタ化する逆 エスケープもある。

viにおいて括弧「( )」は通常文字であり括弧自身を表す。これをエスケー プしてメタキャラクタ化した「\( \)」は、\(と\)で囲まれたパターンを特別 な格納領域(ホールドバッファ)に保存する機能を持つ。それを使うのは複雑 な正規表現であり滅多に使わない。数こそ少ないが通常文字のエスケープが メタキャラクタになる場合の一例がこの「\( \)」である。

正規表現のメタキャラクタとして使う文字については、それぞれのエディタ とか文字処理言語により微妙に異なる。viとemacsでも違いがある。また、 sed, awk, Perlとかでも大まかには似ているが細部は一致しない。それぞれ の方言に注意して使うしかない。

vimを使って空行に残っている空白を検索しようとする。空行に紛れ込んで いる無駄な空白を除去したい。そこで「/^ *$」を試してみる。「*」は直前 の文字の任意の回数の繰り返しにマッチする。ここにいう任意回にはゼロ回 を含む。したがって空白のない第一カラムに改行文字だけがあるまったくの 本物空行「/^$」にもマッチする。空行に紛れ込んでいる空白を見つけるに は邪魔である。

空行に紛れ込んでいる一個以上の空白を見つけるようにしたい。vim解説本 をチラッと見ると「+」が一回以上の繰り返しにマッチするとある。スクリ プト言語のPerlの正規表現と同じと思い「/^ +$」としてみる。ところが実 際に空白があるはずの偽物空行がヒットしない。

最初に見たvim本は「はじめてのvi&vim」技術評論社で、次に「入門vi第6 版」オライリージャパンを見る。後者では裸の「+」ではなくバックスラッ シュを前置した「\+」になっている。さっそく「/^ \+$」とすると偽物空行 に残っている空白にヒットした。

なんで「+」をバックスラッシュ\でエスケープするのだろうと解説本を読み 直す。その理由は、viでは「+」が正規表現のメタキャラクタではないことに ある。

vimはviと互換性を保つために裸の「+」をメタキャラクタとして扱わない。 そこで「+」を通常の文字からメタキャラクタ化するために逆エスケープす る。バックスラッシュを前置した「\+」がvimにおける正規表現のメタキャ ラクタになる。

正規表現におけるメタキャラクタを通常の文字と認識させるにはバックス ラッシュでエスケープする。しかし、数こそ少ないが上記のように通常文字 をメタキャラクタ化する逆エスケープもある。うっかりしていてそのことに 気付かなかった。「はじめてのvi&vim」技術評論社もしっかり読むと「+」 はエスケープすると書いてある。単に「+」とし注意書きでエスケープ必要 とするか、実際の使用形で「\+」と書いてあるかの違いであった。

最初に試した「/^ +$」では第1カラムに空白、そして第2カラムに+が入った 行にマッチする。そんな行はどこにも無かったので「下まで検索したけれど 該当個所がありません」のメッセージが出る。行の先頭に「 +」を打ち込む と「/^ +$」で検索されることにようやく気付く。

なお「/^ \+$」は「/ \+$」に含まれる。偽物空行や行末の空白を探すには 後者だけでよい。インデントの空白にはヒットしない。

「大変便利なことに、検索キーワードには正規表現を適用できる(正確に は、正規表現しか受け付けない。普通の文字列とて立派な正規表現であ る)。 例えば、[Kk]eywordという指定をすれば、keywordとKeywordの両方 にマッチするし hoge$と指定すれば行末にhogeと入力されている部分にマッ チする。 正規表現についての説明はそれだけでこのコンテンツを遙かに上 回る文章量になるので割愛。・・・私もあんまり詳しくないし。
正規表現は、是非覚えておくことを勧めるが、別に知らなくても検索はでき るので強要する気もない。ただし、覚えなくても、注意しなければならない 事柄がある。というのは、正規表現で特殊文字(メタ文字という)扱いになる [ ] * . + ^ $ &等は、そのままではその文字自体をキーにすることができ ないのである。
例えばx*yという文字列を探そうとして/x*yのように指定してもマッチしな い。x*は「0個以上のxがある」という意味の正規表現であると見なされるた め、マッチするのはy、xy、xxy等である。狙い通りに検索するには、/x\*y のように\を特殊文字の頭に付加しなければならない(エスケープする、と いう)。普通の文字に\を付加しても無視されるだけなので、怪しいと思う 文字にはとにかくつけてみると良い。」
「正規表現にはメタ文字と言うものがあり、これらの文字は正規表現中で特 別な意味を持ちます。しかし、メタ文字をリテラルとして使用したい場合い ちいちエスケープする必要があり面倒です。そのために、Vimの正規表現に はmagic、very magicと言う概念があります。
Vimの正規表現にはメタ文字の処理に関して4つの状態があり、状態によって どの文字がメタ文字であるかが変わります。
  1. very magic
  2. magic
  3. nomagic
  4. very nomagic
下に行くほど記号はリテラル文字として扱われます。very magic は全ての 記号はメタ文字として扱われ、 very nomagic はバックスラッシュ以外の記 号は全てリテラル文字として扱われます。 magic と nomagic はどの文字が メタ文字として扱われるかはまちまちです。help で確認してください。
文字として扱われる文字もバックスラッシュを前置することでメタ 文字として扱えます。例えば.(任意の1字を表すメタ文字)はnomagicの際は リテラル文字ですが、\.とすることでメタ文字として扱えます。
それぞれの状態は正規表現中に \v \m \M \V を置くことで切り替えます。 これは書かれた箇所以降で有効になります。 つまり、1 つの正規表現中で 途中で状態を変更することができます。
これは逆に言うと、複数の任意の正規表現を文字列として結合した場合、以 前がどの状態になっているかわからないことを意味します。 正規表現を結 合するような処理を行う場合、各正規表現の先頭で状態を設定しておいた方 が良いでしょう。
magic の初期値は 'magic' オプションで決まります。boolean 型のオプ ションで、on だと magic、off だと nomagic になります。 オプション自 体のデフォルト値は on です。」

このことはpattern.txtに書かれているが、最初にそれを見たとき何のこと なのかさっぱり分からなかった。上記記事と合わせてようやくそういうこと かと納得できた。

| | コメント (0) | トラックバック (0)

2010年6月26日 (土)

機械式タイプライター(typewriter)にバックスラッシュ(backslash)はない

機械式タイプライター(typewriter)にバックスラッシュ(backslash)はない

Time-stamp: "Mon May 03 11:07:02 JST 2010"

バックスラッシュでググると通貨の円記号は打てるが逆斜め線の本物バック スラッシュが出せないという話題が多い。それはともかくとして、そもそも バックラッシュは何のための記号なんだろう。

スラッシュは機械式タイプライターにそのキーがある。しかし、バックス ラッシュはない。いったいバックスラッシュは何のために何時頃から使われ たのだろうか。英語版wikipediaによると1960年頃からのようである。

バックスラッシュはリバース・ソリダス(reverse solidus)とも呼ばれる。 ソリダス(solidus)とはローマ帝国後期の金貨でsolid(固い、金貨)による。 sの長形∫から/に変化したものという。以前の英国の金額表示で 2/6 (2 シ リング(shilling) 6 ペンス(pence))のように使われていた。

コンピュータで使われるようになった記号なので機械式タイプライターの時 代にはなかったものである。algol言語においてバックスラッシュと組み合 わせて論理和記号(v字形)と論理積記号(ギリシア文字ラムダの大文字Λ字 形、逆v字形)を表すために使われたらしい。現在は論理和として「||」、論 理積として「&&」を使うのが普通である。

UNIXのシェルのコマンドラインや、スクリプト言語の正規表現において、特 殊な意味を持つ記号(メタ文字)の前に記述し、その意味を打ち消し単なる 文字(リテラル)として扱う。正規表現においては、逆に特殊な意味を付与す ることもある。\( \)、 \1 など。

「IS X 0201は、米国で制定された文字コードであるASCIIをベースにした国 際規格のISO/IEC 646に基づくものである。ISO/IEC 646は128文字分の領域 を持つコード体系だが、このうち12文字は各国で自由に決めてもよい領域と されていた。JIS X 0201で円記号が割り当てられた0x5C番地はこの12文字の 1つであり、本家の米国版ASCIIではバックスラッシュ(\)記号が割り当て られていた番地である。
バックスラッシュは、MS-DOSではディレクトリ名を区切る記号として、C言 語なら文字列の中で特殊文字を意味する記号として扱われるなど、ISO/IEC 646で未定義の文字を、各種オペレーティングシステムやプログラミング言 語、その他のソフトウェアで制御コードとして使用するという誤った使用が 一般化してしまった。
日本語用の文字コードにはバックスラッシュが存在せず、同じ0x5C番地に円 記号が割り当てられているのであるが、これらのソフトウェアでは0x5C番地 の文字が制御コードとして扱われるようにされていたため、日本語用文字 コードでは円記号が同等の制御コードとして解釈されることになった。」
「制御記号は0/0~1/15の32文字、2/3は`£'または`#'のどちらか、4/0 (@)、5/14(^)、6/0(`)は推奨文字があるものの事情によっては変更 可能、そして5/11~5/13と7/11~7/13は自由領域とする最終案が確定した。 さらに2/4を`$'と`?'(国際通貨記号) のどちらでも実装可にしたBCT (Basic Code Table)版、2つ目は2/3, 2/4, 4/0, 5/11~5/14、7/11~7/13 に全て推奨文字を割り当てたIRV(International Reference Version; 国際 基準版)である。ただしIRV版はASCIIと比較し、2/4は`?'であり、また7/14 はオーバーラインである点が異なっていた。」

ISO/IEC 646は128文字分の領域を持つコード体系だが、このうち次の12文字 は各国で自由に決めてもよい領域とされていた。

2324405b5c5d5e607b7c7d7e
#$@[\]^`{|}~
「バックスラッシュって何のためにあるのかと思っていたが、スラッシュと 組み合わせて論理記号を書くためにあったのか. 日本では(ry」
``The backslash (\) is a typographical mark (glyph) used chiefly in computing. It was first introduced to computers in 1960 by Bob Bemer. Sometimes called a reverse solidus or a slosh, it is the mirror image of the common slash.
Other common terms for the character include hack, escape (from C/UNIX), reverse slash, backslant, whack, and backwhack. Also, it is sometimes referred as bash, reverse slant, reversed virgule, or backslat.
Bob Bemer introduced the \ character into ASCII, on September 18, 1961, as the result of character frequency studies. In particular the \ was introduced so that the ALGOL boolean operators "∧" (AND) and "∨" (OR) could be composed in ASCII as "/\" and "\/" respectively. Both these operators were included in early versions of the C programming language supplied with Unix V6 , Unix V7 and more currently BSD 2.11.
In many programming languages such as C and Perl and in Unix scripting languages, the backslash is used to indicate that the character following it should be treated specially. It is sometimes referred to as a knock-down or escape character. In various regular expression languages it acts as a switch, changing literal characters into metacharacters and vice versa. The backslash is used similarly in the TeX typesetting system and in RTF files to begin markup tags. In Haskell, the backslash is used both to introduce special characters and to introduce lambda functions (since it is a reasonable approximation in ASCII of the Greek letter lambda, λ).
In the context of line-oriented text, especially source code for some programming languages, it is often used at the end of a line to indicate that the trailing newline character should be ignored, so that the following line is treated as if it were part of the current line. In this context it may be called a "continuation". The GNU make manual says
We split each long line into two lines using backslash-newline; this is like using one long line, but is easier to read.''

| | コメント (1) | トラックバック (0)

2010年6月10日 (木)

長方形用紙の縦横比(paper size)

長方形用紙の縦横比(paper size)

Time-stamp: "Sat Apr 24 10:42:10 JST 2010"

A版とB版がある。縦横比は1:√2である。A0版の面積は1 m3であり、 B0版は1.5 m3である。

  • A0版は841×1189 mmである(ドイツ規格DINに由来)。
841×1189=999,949 mm3
1189÷841≒1.4137931
  • B0版は1030×1456 mmである(日本独自規格、美濃紙に由来)。
1030×1456=1,499,680 mm3
1456÷1030≒1.4135922

AO版用紙の長辺方向の二つ折がA1版用紙になる。それらは相似な長方形であ る。その縦横比を求める。

長方形の長辺方向の長さをx(>1)とし短辺方向の長さを1(単位)とする。 なお、長方形の長辺方向の中央で二つ折りにしてできる長方形はそれまでに長 辺だったものが短辺に、短辺だったものが長辺に入れ替わる。二つ折りにする 前と後で短辺と長辺方向の長さの比が変わらないとすると

短辺:長辺=1:x=x/2:1

x2=2 から x=√2 となる。だいたい1対1.414同じく0.707対1 の比になる。

長辺の半分が次の短辺になり、短辺はそのままで次の長辺になる。

長辺√21(√2)/21/2(√2)/4
短辺1(√2)/21/2(√2)/41/4
長/短√2√2√2√2√2
「暗記用語呂合わせ:1189いい役×841欲しい=A0え~男、210日当×297付く なら=A4え~よ」

| | コメント (0) | トラックバック (0)

« 2010年5月 | トップページ | 2010年7月 »