読者です 読者をやめる 読者になる 読者になる

HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

空白文字の判定

正規表現を使って空白文字を判定する処理に関して、認識と違っていた部分があったのでメモ。
preg_match関数に指定する正規表現で使用可能なエスケープシーケンスとして「\s」というのは知っているのだが、他にも以下のものがあるらしい。

\h
水平方向の空白文字 (PHP 5.2.4 以降)
\H
水平方向の空白文字でない文字 (PHP 5.2.4 以降)
\s
空白文字
\S
空白文字でない文字
\v
垂直方向の空白文字 (PHP 5.2.4 以降)
\V
垂直方向の空白文字でない文字 (PHP 5.2.4 以降)

確かに、水平タブとか垂直タブとかあるな、と。
で、「/\s/」は「/[\h\v]/」かと思ったら、どうやら違うらしい。
そこで、検証プログラムを書いて試してみる。

<?php
$chars = array(
    'SP'     => " ",
    'HT(\t)' => "\t",
    'NL(\n)' => "\n",
    'NP(\f)' => "\f",
    'VT(\v)' => "\v",
    'CR(\r)' => "\r",
);
printf("| %8s |  %2s  |  %2s  |  %2s  |  %2s  |  %2s  |  %2s  |\n",
    '', '\s', '\h', '\v', '\S', '\H', '\V');
foreach ($chars as $key => $ch) {
    printf("| %-8s | ", $key);
    printf(" %-2s  | ", preg_match('/^\s/', $ch) ? "O" : "X");
    printf(" %-2s  | ", preg_match('/^\h/', $ch) ? "O" : "X");
    printf(" %-2s  | ", preg_match('/^\v/', $ch) ? "O" : "X");
    printf(" %-2s  | ", preg_match('/^\S/', $ch) ? "O" : "X");
    printf(" %-2s  | ", preg_match('/^\H/', $ch) ? "O" : "X");
    printf(" %-2s  |\n", preg_match('/^\V/', $ch) ? "O" : "X");
}

で、実行結果。

|          |  \s  |  \h  |  \v  |  \S  |  \H  |  \V  |
| SP       |  O   |  O   |  X   |  X   |  X   |  O   |
| HT(\t)   |  O   |  O   |  X   |  X   |  X   |  O   |
| NL(\n)   |  O   |  X   |  O   |  X   |  O   |  X   |
| NP(\f)   |  O   |  X   |  O   |  X   |  O   |  X   |
| VT(\v)   |  X   |  X   |  O   |  O   |  O   |  X   |
| CR(\r)   |  O   |  X   |  O   |  X   |  O   |  X   |

文字の表記はASCII文字コード : IT用語辞典にしたがっている。
スペース(SP)や水平タブ(HT)は想像通りとして‥
いわゆる改行コード(NL(LF)やCR)や改ページ(NP)は、垂直方向の空白文字(「\v」)に分類されるが、空白文字(「\s」)であるらしい。
一方、垂直タブ(VT)は、垂直方向の空白文字であるが、空白文字(「\s」)ではないらしい。

VTなんてめったに来ないだろうが、空白全部除去とか言って「/\s/」とだけ書くと、厳密にはアウトで、「/[\s\v]/」または「/[\h\v]/」と書かないといけないらしい。