@blog.justoneplanet.info

日々勉強

preg_matchにおける$の注意点

preg_matchにおける$の挙動を知る。

<?php
$str = "01237";
$str = preg_replace("/37$/", '', $str);
var_dump($str);
//string(3) "012"

当然だ。次に以下を実行する。

$str = "01237\n";
$str = preg_replace("/37$/", '', $str);
var_dump($str);
//string(4) "012\n"

ん?文字列の最後尾の改行コードが$で捉えきれなかった。

$str = "01237\n";
$str = preg_replace("/37$/D", '', $str);
var_dump($str);
//string(6) "01237\n"

上述のようにDオプションを加えると期待した動作になる。

■まとめ

$
行の末尾
D
$を検索対象文字列の終わりにのみマッチ。これが無い場合、$は改行文字の前でもマッチする

従って前述のコードの様な結果となる。

PHP Perl-compatible Regular Expressions(Perl互換正規表現)

正規表現を使うと非常に複雑な文字列の抽出、検索や置換、分割が行える。正規表現とは検索パターンを表す文字列である。PHPではPOSIXの正規表現とPerlの正規表現をサポートしている。Perl-compatible Regular Expressionsは略してPCREと呼ばれる。

Perl互換正規表現 POSIXの正規表現
速度
機能
読みやすさ

最後の読みやすさについて、個人的にはPerl互換正規表現の方が読みやすいとは思う。

■PCRE正規表現の区切り文字

慣例ではスラッシュ「/」が使用されるが、urlなどを正規表現で表す際に、エスケープするのが面倒になるので#が使われることもある。通常では使用されないが、英数字とバックスラッシュ以外の文字ならば区切り文字として使用が可能である。

<?php
if(preg_match('/[a-z]/', 'string')){
    //code
}
if(preg_match('#(http://|https://)[a-zA-Z0-9./_-]+#', 'http://justoneplanet.info/')){
    //code
}
?>

■文字クラス

. 任意の一文字にマッチする
^ 文字列の最初にマッチする、もしくは行の先頭にマッチする(mフラグが有効な場合はnの次の文字)
$ 文字列の最後にマッチする、もしくは行の末尾にマッチする(mフラグが有効な場合はnの前の文字)
s 改行コード、半角スペース(全角スペースは含まない)、タブにマッチする [rn t]
d 全ての数字にマッチする [0-9]
D 全ての数字以外にマッチする [^0-9]
w 単語に使用する文字(アルファベット等)にマッチする [0-9a-zA-Z_]
W 単語に使用する文字(アルファベット等)以外にマッチする [^0-9a-zA-Z_]

全角スペースの扱いには要注意だ。その辺りが初心者のときは全然わからなかった。。。

■量指定子

貪欲 貪欲でない
* 直前の文字の0個以上の繰り返し *?
+ 直前の文字の1個以上の繰り返し +?
? 直前の文字が0個もしくは1個だけ存在する(直前の文字が繰り返しではないことを意味する) ??
{n} 直前の文字がn個繰り返し {n}?
{n,} 直前の文字が少なくともn個繰り返し {n,}?
{n,m} 直前の文字が最低n個、m個以下の繰り返し {n,m}?

貪欲でない量指定子の使用法

以下のように通常「.*」を使用すると、一つ目のstrongタグの開始から二つ目のstrongタグの終了までマッチしてしまう。残りのパターンを満たす限りできるだけ短い範囲でマッチするようにするには貪欲でない量指定子を使用する。

<?php
preg_match('/(<.*>)/', '<strong>PHP</strong>のPerl互換正規表現', $match);
var_dump($match);
/*
array(2) {
  [0]=>
  string(20) "<strong>PHP</strong>"
  [1]=>
  string(20) "<strong>PHP</strong>"
}
*/
preg_match('/(<.*?>)/', '<strong>PHP</strong>のPerl互換正規表現', $match);
var_dump($match);
/*
array(2) {
  [0]=>
  string(8) "<strong>"
  [1]=>
  string(8) "<strong>"
}
*/
?>

但し、以下のコードの方が高速である。

<?php
preg_match('/(<[^>]*>)/', '<strong>PHP</strong>のPerl互換正規表現', $match);
var_dump($match);
/*
array(2) {
  [0]=>
  string(8) "<strong>"
  [1]=>
  string(8) "<strong>"
}
*/
?>

■選択肢

以下のように「|」の記号を使って正規表現内で選択肢を指定することができる。

<?php
preg_match_all('/dog|cat/i', 'Dogs and Cats is so cute!!', $matches);
var_dump($matches);
/*
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(3) "Dog"
    [1]=>
    string(3) "Cat"
  }
}
*/
?>

但し「dogもしくはcatで始まる文字列」とする場合、以下のようにグルーピングしなければならない。

<?php
preg_match_all('/^(cat|dog)/i', 'Dogs and Cats is so cute!!', $matches);
var_dump($matches);
/*
array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(3) "Dog"
  }
  [1]=>
  array(1) {
    [0]=>
    string(3) "Dog"
  }
}
*/
?>

■サブパターン

パターンの一部を()で括ると後でキャプチャとして使用することができる。また、以下のようにグルーピングしてパターン化することができる。

<?php
preg_match('/(abc)+/', 'abcabcbbceed', $match);
var_dump($match);
/*
array(2) {
  [0]=>
  string(6) "abcabc"
  [1]=>
  string(3) "abc"
}
*/
?>

上述の例では、グルーピングしたabcの繰り返しにマッチするかどうかがチェックされる。また、$match[1]にはキャプチャした文字列が格納されている。ちなみにキャプチャする必要がない場合は以下のようにする。

<?php
preg_match('/(?:abc)+/', 'abcabcbbceed', $match);
var_dump($match);
/*
array(1) {
  [0]=>
  string(6) "abcabc"
}
*/
?>

■後置きオプション

i 大文字、小文字を区別しない
m ^を改行直後の文字、$を改行直前の文字にマッチさせる(マルチラインモード)
e 置換文字にPHPのコードを指定すると、evalした結果で文字列を置き換える(使い方によっては危険)

後置きオプションは以下のように使用する。

<?php
preg_match('/(?:abc)+/i', 'abcabcbbceed', $match);
var_dump($match);
/*
array(1) {
  [0]=>
  string(6) "abcabc"
}
*/
?>

■先読みと戻り読み

以下全てキャプチャは行わない。

(?=pattern) 肯定先読み
(?!pattern) 否定先読み
(?<=pattern) 肯定戻り読み
(?<!pattern) 否定戻り読み

先読み(次の文字が~だったら)と、戻り読み(前の文字が~だったら)は以下のように使用する。

<?php
preg_match('/(?<=<h4>).+(?=[0-9])/', '<h4>story1', $match);
var_dump($match);
/*
array(1) {
  [0]=>
  string(5) "story"
}
*/
?>

これは非常に強力である。ちなみに、JavaScriptには「戻り読み」が存在しない。

■Perl互換正規表現での文字列のマッチングと抽出

文字列のマッチングと抽出を行うには、以下のようにpreg_match関数を使用する。第一引数では検索パターンを指定し、第二引数では対象文字列を指定する。以降はオプションで、第三引数ではマッチした文字列が格納される変数を指定する。

<?php
$str = 'She sells seashells.';
if(preg_match('/she/im', $str, $matches)){
    var_dump($matches);
}
/*
array(1) {
  [0]=>
  string(3) "She"
}
*/
?>
<?php
$str = 'She sells seashells.';
if(preg_match('/(She)s(sell)s*s(seashell)s*/', $str, $matches)){
    var_dump($matches);
}
/*
array(4) {
  [0]=>
  string(19) "She sells seashells"
  [1]=>
  string(3) "She"
  [2]=>
  string(4) "sell"
  [3]=>
  string(8) "seashell"
}
*/
?>

preg_match関数は、1回マッチした時点で検索を終了するので、戻り値が1より大きくなることはない。従って、全て検索させたい場合には、以下のようにpreg_match_all関数を使用する。

<?php
$str = 'She sells seashells.';
if(preg_match_all('/she/i', $str, $matches)){
    var_dump($matches);
}
/*
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(3) "She"
    [1]=>
    string(3) "she"
  }
}
*/
?>

各関数について

int preg_match(string $pattern, string $str[, array $matches])
マッチした回数を返すが0か1となる。従って、全て調べるにはpreg_match_all関数を使用しなければならない。マッチした部分については$matchesに格納される。
int preg_match_all(string $pattern, string $str, array $matches)
パターンがマッチした総数を返す(0も含む)。但しエラーが発生した場合はfalseを返す。

■Perl互換正規表現での文字列の置換

以下のようにpreg_replace関数を使って、Perl互換正規表現での文字列置換を行う。この例では独自のタグをHTMLタグに変換する処理を行っている。いくつかのCMSにはこのようなタグが導入されている。これはユーザーのHTML入力を安全にする方法の一つである。

<?php
$str = '[b]Make Me Bold![/b]';
$str = preg_replace('#[b](.*?)[/b]#i', '<strong>$1</strong>', $str);
var_dump($str);
/*string(30) "<strong>Make Me Bold!</strong>"*/
?>

また、以下のように検索パターンと置換文字列に配列を指定することもできる。

<?php
$subjects['body'] = '[b]Make Me Bold![/b]';
$subjects['title'] = '[i]Make Me Italics![/i]';

$reg[] = '#[b](.*?)[/b]#i';
$reg[] = '#[i](.*?)[/i]#i';

$rep[] = '<strong>$1</strong>';
$rep[] = '<i>$1</i>';

$results = preg_replace($reg, $rep, $subjects);
var_dump($results);
/*
array(2) {
  ["body"]=>
  string(30) "<strong>Make Me Bold!</strong>"
  ["title"]=>
  string(23) "<i>Make Me Italics!</i>"
}
*/
?>

検索パターンの配列と置換文字列の配列の長さを比較し、検索パターンが多く置換文字列がない場合は空文字が置換文字列となる。また検索パターンのみ配列ということもあり得る。

各関数について

mixed preg_replace(mixed $pattern, mixed $replace,mixed $str)
正規表現$patternでマッチングを行い$replaceに置換する。

PHP Formatting Strings(文字列の整形)

■数字の整形

以下のように、PHPではnumber_format関数を使用して、数字を整形することができる。その時の引数の数として成立するパターンは以下の通りである。第二引数では小数以下の桁数を明示し、第三引数と第四引数で小数点の区切りと千単位の区切りを明示する。

<?php
$num = '100000000.12345';
print(number_format($num));//100,000,000
print(number_format($num, 3));//100,000,000.123
print(number_format($num, 3, '.', ','));//100,000,000.123
?>

各関数について

string number_format(float $num[, int $decimals[, string $dec_point, string $thousand_sep]])
1つ、2つ、4つの引数をとる。第一引数にはフォーマットする数字を指定し、第二引数では小数点以下の桁数を表示する。第三引数と第四引数は、それぞれ小数点の区切り文字と千ごとの区切り文字を指定する。

少し話が逸れてしまうが、フランスなどでは千単位の区切りにスペース(もしくはドット)を使用し、小数と整数の区切りにカンマを使うようだ。

■地域に依存した文字列の整形

ロケール情報のセット

以下のようにsetlocale関数を使用して、地域情報をセットする。第一引数ではカテゴリを指定し、第二引数ではロケールを文字列もしくは配列で指定する。

<?php
setlocale(LC_MONETARY, 'en_US');
?>

ロケールに基づいた文字列の整形

以上をふまえて、金額文字列に変換するには以下のようにmoney_format関数を使用する。但し、この関数はWindows環境(Windowsサーバー)では現在のところ使用できない。

<?php
$num = '100000000.98765';
setlocale(LC_MONETARY, 'en_US');
print(money_format('%.2n', $num));//$100,000,000.99

setlocale(LC_MONETARY, 'ja_JP.UTF-8');
print(money_format('%.2n', $num));//¥100,000,000.99
?>

小数が不要の場合は、以下のコードの後者のようにすれば良い。

<?php
$num = '100000000.796';
setlocale(LC_MONETARY, 'en_US');
print(money_format('%.2i', $num));//USD 100,000,000.80

setlocale(LC_MONETARY, 'ja_JP.UTF-8');
print(money_format('%i', $num));//JPY 100,000,001
?>

各関数について

string setlocale(int $category, string $locale)
第一引数のカテゴリにおいて、第二引数のロケールを設定する。
string money_format(string $format, float $num)
数値を金額文字列にフォーマットする。

フォーマット文字について

% 文字をそのまま返す。
. ピリオドに続く数字で小数の桁数を指定する。この桁数に出力が丸められる。
i ロケールの国際フォーマットでフォーマットする。
n ロケールの国内フォーマットでフォーマットする。

■書式文字列を指定した整形

以下のようにprintf関数は、書式文字列を指定された値で置き換えた文字列を出力する。但し、出力せずにデータとして扱いたい場合は、sprintf関数を使用する。また、%を出力したいときは%%と記述する。

<?php
$year = '2009';
$month = '4';
$day = '26';
printf('%04d/%02d/%02d', $year, $month, $day);//2009/04/26
//$date = sprintf('%04d/%02d/%02d', $year, $month, $day);
?>

どうもC言語の経験がないせいか、よく分からん・・・そんなときは書いて覚えるべし。

<?php
for($i = 0; $i < 101; $i = $i + 10){
    printf('%.2f%% 完了しました', $i);
}
/*
0.00% 完了しました
10.00% 完了しました
20.00% 完了しました
30.00% 完了しました
40.00% 完了しました
50.00% 完了しました
60.00% 完了しました
70.00% 完了しました
80.00% 完了しました
90.00% 完了しました
100.00% 完了しました
*/
?>

やはりコノ関数は日付の整形時にもっとも見かける。従って、もう一度。

<?php
$year = 2008;
$month = 6;
$day = '1';
printf('%04d/%02d/%02d', $year, $month, $day);
/*
2008/06/01
*/
?>

各関数について

int printf(string $format[, mixed $args[, mixed $args, …]])
文字列などをフォーマットして出力する。
string sprintf(string $format[, mixed $args[, mixed $args, …]])
文字列などをフォーマットして返す。
%の後に続く指定子
-もしくは+ 符号指定子。デフォルトでは整数が負の値のときだけ、-が付く。
パディング指定子 指定の桁数に足らなかったときに、詰める文字。スペースもしくは0のみ指定可能。
表示幅指定子 出力の桁数を指定する。
精度指定子 小数点の桁数を指定する。
型指定子
% 引数は不要
d 引数を10進数の整数として扱う
e 引数を科学記法として扱う

■フォーマットに基づいた文字列の分解

PHPでは以下のようにsscanf関数を使って、printf風のフォーマットに基づき文字列を分解できる。

<?php
$str = '123 456 789';
$format = '%d %d %d';
var_dump(sscanf($str, $format));
/*
array(3) {
  [0]=>
  int(123)
  [1]=>
  int(456)
  [2]=>
  int(789)
}
*/
$str = '123 aaa 789';
$format = '%d %d %d';
var_dump(sscanf($str, $format));
/*
array(3) {
  [0]=>
  int(123)
  [1]=>
  NULL
  [2]=>
  NULL
}
*/
?>

うーん、イマイチ有用性がわからん。。。

各関数について

mixed sscanf(string $str, string $format)
フォーマット文字列で文字列を処理する。

PHP Comparing, Searching and Replacing String(文字列の比較検索置換)

■文字列の比較

以下のようなコードを書いた場合、条件はtrueとなることに注意せねばならない。条件部分で$strがint型に自動で変換される為である。(808desu → 808)

<?php
$str = '808desu';
if($str == '808'){
    //code
}
?>

上述のような型の動的変換を予期した上でのコードは、自身の可読性を非常に下げる。従って、以下のようなコードを書くことをお勧めする。

<?php
$str = '808desu';
if($str === '808'){
    //code
}
?>

こういったコードにすれば、誰もが予期するように条件はfalseとなる。

文字列比較関数

以下のように、PHPには文字列を比較する関数も用意されている。

<?php
$str = '808desu';
if(strcmp($str, '808desu') === 0){
    //code
}
?>

strcmp関数は第一引数の文字列と第二引数の文字列を比較し、等しいときは0、第一引数が第二引数よりも大きいときは差分を正の値で返し、逆のときは差分を負の値で返す。また、以下のように大文字と小文字を区別しないstrcasecmp、最初のn文字までを比較するstrncasecmp関数もある。

<?php
$str = '808desu';
if(strcasecmp($str, '808Desu') === 0){
    //code
}
?>
<?php
$str = '808desu';
if(strncasecmp($str, '808Desukedo', 7) === 0){
    //code
}
?>
各関数について
int strcmp(string $str1, string $str2)
$str1を$str2と比べたときに、小さかったら負の数、大きかったら正の数、等しいかったら0を返す。
int strcasecmp(string $str1, string $str2)
大文字と小文字を区別しない。
int strncasecmp(strng $str1, string $str2, int $length)
はじめの$lengthだけ比較対象とする。但し、$lengthよりも一方が短い場合は、その文字数に合わせる。

正直なところ、暗記するコストの方が高くつくこの手の関数の有用性は理解に苦しむ。まぁそれがPHPの良いところでもあるのかもしれない。

■単純な文字列の検索

文字列の位置情報

PHPには以下のように、文字列の位置を返すstrpos関数がある。この関数は対象文字列に検索文字列が見つからなかったとき、falseを返す。従って条件文では、0が戻ることを考慮し以下のようにしなければならない。

<?php
$haystack = 'Mike's car';
$needle = 'Mike';
if(strpos($haystack, $needle) !== false){
    //code
}
?>

また以下のように、strpos関数は第三引数にオフセット値を指定できる。

<?php
$haystack = 'Mike's car. Mike's bike';
$needle = 'Mike';
print(strpos($haystack, $needle));//0
print(strpos($haystack, $needle, 1));//12
?>

strpos関数には大文字と小文字を区別しないstripos関数がある。

文字列の位置と部分文字列

文字列内から検索文字列以降を得たい場合は以下のように、strstr関数を使用する。但し、単純な文字列検索の場合は、より高速に動作するstrpos関数を使用するべきである。

<?php
$haystack = 'This is Mike's car';
$needle = 'Mike';
print(strstr($haystack, $needle));//Mike's car
?>

strstr関数には大文字と小文字を区別しないstristr関数がある。

関数によって「case」が付くものと「i」が付くものがあるが、これはPHPの統一性に欠ける面だと個人的には思う。

文字列のマスキング処理

以下のようにstrspn関数は、文字列の最初からマスキングし、一致文字列の長さを返す。ホワイトリスト方式である。また、ブラックリスト方式の関数としてstrcspn関数がある。

<?php
$str = '13927abccdestt';
$allowed_characters = '123456789';
print(strspn($str, $allowed_characters));//5
?>

以下のようにstrspn関数は、第三引数に対象文字列のオフセット値、第四引数に対象文字列の長さを指定できる。

<?php
echo strspn("foo", "o", 1, 2); // 2
?>

個人的には、この関数を使ったことはない。

各関数について
int strpos(string $str, string $needle)
文字列$strの中で$needleが最初に見つかる位置を返す。但し、見つからなかった場合は「false」を返す。
string strstr(string $str, string $needle)
文字列$strの中で$needleが最初に見つかる位置を含めた残りの文字列を返す。
int strspn(string $str, string $mask[, int $start[, int $length]])
文字列の先頭から何文字目までが$maskの条件を満たしているかを返す。第三引数にはオフセット値、第四引数には対象文字列の長さを指定できる。

■文字列の置換

文字列による検索と置換

以下のようにstr_replace関数を使って、検索文字列に一致したすべての文字列を置換する。

<?php
$search = 'John';
$replace = 'Nick';
$str = 'Hello, John!';
$str = str_replace($search, $replace, $str);
print($str);//Hello, Nick!
?>

また以下のように、置換対象の個数を知ることもできる。

<?php
$search = 'John';
$replace = 'Nick';
$str = 'Hello, John!';
$str = str_replace($search, $replace, $str, $counter);
print($counter);//1
?>

大文字と小文字を区別しないようにするには、str_ireplace関数を使用する。

部分指定による検索と置換

以下のようにsubstr_replace関数を使用する。第一引数は対象文字列、第二引数は置換文字列、第三引数はオフセット値、第四引数は置換される文字列の長さ。第四引数を指定しなかった場合は、オフセット値から最後までが置換対象となる。

<?php
$str = 'sample@test.com';
$replace = 'Nick';
$str = substr_replace($str, $replace, 0, 6);
print($str);//Nick@test.com
?>

以上を踏まえると以下のような使用例が考えられる。

<?php
$email = 'mike@sample.com';
$user = substr_replace($email, '', strpos($email, '@'));
print($user)//mike;
?>
各関数について
string str_replace(mixed $search, mixed $replace, mixed $subject[, int &$count])
対象文字列から検索文字列を全て置換文字列に変換します。
string str_ireplace(mixed $search, mixed $replace, mixed $subject[, int &$count])
大文字と小文字を区別しないstr_replace関数。
mixed substr_replace(mixed $str, string $replace, int $start[, int $length])
$start番目から$length分の文字列を$replaceに変換する。

■文字列の抽出

以下のようにsubstr関数を使用すると、文字列から一部分を抽出できる。

<?php
$str = 'She sells sea shells on the sea shore.';
print(substr($str, 0, 3));//She
print(substr($str, 4, 5));//sells
print(substr($str, 21));//on the sea shore.
?>

また以下のように第二引数には負の値を指定することができる。その場合、オフセット値は後ろから数え、そこから正の方向に第三引数分抽出することになる。

<?php
$str = 'She sells sea shells on the sea shore.';
print(substr($str, -1, 1));//.
print(substr($str, -6, 5));//shore
?>

各関数について

string substr(string $str, int $start[, int $length])
文字列を$startの位置から$lengthバイト切り出す。$lengthに負の値を与えると、最後から数えて$length分だけ結果から切り落とされる。

■文字列の分解と結合

以下のようにexplode関数を用いて、文字列を任意の文字で分解することができる。

<?php
$str = 'John,Jack,Nick';
$names = explode(',', $str);
var_dump($names);
/*
array(3) {
  [0]=>
  string(4) "John"
  [1]=>
  string(4) "Jack"
  [2]=>
  string(4) "Nick"
}
*/
?>

また、以下のようにimplode関数を用いて、配列を任意の文字列で結合することができる。

<?php
$names = array('Nick', 'Mike', 'Fred');
$str = implode(',', $names);
var_dump($str);
/*
string(14) "Nick,Mike,Fred"
*/
?>

各関数について

array explode(string $separator, string $str)
文字列を$separatorで分割し配列にする。
string implode(string $separator, string $str)
配列を$separatorで結合し文字列を返す。

PHP String Basics(文字列の基本)

■文字列データの使用

JavaScriptではシングルクォートもダブルクォートも同じ扱いであるが、PHPでは変数の展開において挙動が異なる。

シングルクォート

通常は以下のようにシングルクォートで括る。最もシンプルで一般的な方法だ。

<?php
$str = 'sample';
?>

シングルクォート内でシングルクォートを文字列として表現するためには、以下のようにエスケープする。エスケープを表現したい時も同様にエスケープする。

但し、その他についてはマーク「」が直接表示される。従って、改行やタブなどを表現したいときは、シングルクォートは使えない。

<?php
$name = 'John's';
$str = 'This is \';
print($name);//John's
print($str);//This is 
?>

ダブルクォート

以下のようにダブルクォートで括ると変数が展開される。

<?php
$name = 'John';
$str = "Hello, $name";
echo $str;//Hello, John
?>

もしも展開される変数名の後にアルファベットが続いている場合、PHPは
変数名を判断できない。従って、以下のように{}で括ってあげる必要がある。

<?php
$fruit = 'apple';
$str = "This is two {$fruit}s";
//$str = "This is two ${fruit}s";
print($str);
?>

個人的には好きではないが、コメントアウトしたような括り方をする人もいるようだ。また、マーク「$」を表示させたい場合は、変数と認識されないように、エスケープされる必要がある。

ヒアドキュメント

以下のようにヒアドキュメント内でも、変数は展開される。自分の環境ではエラーは出なかったが「<<<」と識別子の間にはスペースが1つ以上必要とされる。最初の識別子の後にセミコロンは置かない。最後の識別子の後にはセミコロン、もしくは改行が置かれなくてはならない。また、最後の識別子の前の改行コードのみ削除される。

<?php
$name = 'Jack';
$str = <<< EOD
Hello, $name
My name is Mike.
This is ......
EOD;
print($str);
/*
Hello, Jack
My name is Mike.
This is ......
*/
?>

但し、以下のようなクラスのプロパティにおいて、ヒアドキュメントはパースエラーとなってしまい使用できない。

<?php
class Person {
    $greeting = <<< EOD
Hello, everyone!
EOD;
}
?>

個人的な見解であるが、ヒアドキュメントは可読性が下がると考えている。従って、正直に言ってしまうと嫌いな方である。

■文字列の長さ

以下のようにstrlen関数を使うと、文字列の長さを判定できる。但し、マルチバイト文字を扱うときは、mb_strlen関数を使用しなくては正しい結果が導き出せない。

<?php
$str = 'She said that she likes him';
print(strlen($str));//27
?>

各関数について

int strlen(string $str)
文字列の長さを求める。
int mb_strlen(string $str[, string $encoding])
マルチバイト文字列の長さを求める。

■文字列の変換

以下のようにstrtr関数を使うと、文字列の中の特定の値について変換が行われる。

<?php
$str = 'we';
$str = strtr($str, 'w', 'm');
print($str);//me
?>

また、以下のように連想配列を変換テーブルに設定することもできる。

<?php
$str = 'we';
$str = strtr($str,
    array(
        'w' => 'm',
        'e' => 'y'
    )
);
print($str);//my
?>

但し、以下のような場合は上手くいかない。strtr関数においては検索文字列と変換後文字列の文字数は等しいことが前提であり、長いほうの余分な文字列は無視されるからだ。

<?php
$str = 'She loves him.';
$str = strtr($str, 'She', 'Her dog');
print($str);//Her lovrs eim.
?>

各関数について

string strtr(string $str, string $form, string $to)
string strtr(string $str, array $relace_table)
特定の文字を変換する。

大文字と小文字の変換

以下のような関数を使って大文字と小文字を変換することができる。

<?php
$str = 'johN nortoN';
print(strtolower($str));//john norton
print(strtoupper($str));//JOHN NORTON
print(ucfirst($str));//JohN nortoN
print(ucwords($str));//JohN NortoN
?>
各関数について
string strtolower(string $str)
文字列を小文字にする。
string strtoupper(string $str)
文字列を大文字にする
string ucfirst(string $str)
文字列の最初の文字を大文字にする。
string ucwords(string $str)
単語ごとの最初の文字を大文字にする。

■空白の除去

以下のようにtrim関数を用いて余分な空白を除去することができる。

<?php
$str = '   Pochi ';
print(trim($str));//Pochi
?>

各関数について

string trim(string $str[, string $charlist])
文字列の先頭と末尾からホワイトスペースなどを取り除く。

■URLのエンコードとデコード

URLのエンコード方式には、スペースの扱いが異なる2種類の関数が用意されている。

RFC1738方式

ディレクトリ名などの変換に使用する。

<?php
$str = 'john norton';
print(rawurlencode($str));//john%20norton
?>

application/x-www/form-urlencoded方式

クッキーやクエリ文字列の変換に使用する。但し、クッキーは自動で変換されるので、主にクエリ用に使う。

<?php
$str = 'john norton';
print(urlencode($str));//john+norton
?>
各関数について
string rawurlencode(string $str)
RFC1738方式に基づきURLをエンコードする。
string rawurldecode(string $str)
RFC1738方式に基づきURLをデコードする。
string urlencode(string $str)
application/x-www/form-urlencoded方式に基づきURLをエンコードする。
string urldecode(string $str)
application/x-www/form-urlencoded方式に基づきURLをデコードする。