Search A.I.
Menu
ホーム

メールマガジン ホームページプログラミングテク

Windowsテク
Javaアプレット サンプル
Java Q & A
JavaScript Q & A
Perl Q & A
Perl レッスン
PHP レッスン
PHPテク
MS-DOS コマンド集
UNIX コマンド集
SQL コマンド集
SEの基礎講座
WEBシステム開発受注します
]無料フォームメール送信サービス
リンク集
PHP レッスン

1. PHP の基礎
2. PHPの文法、条件式
3. PHPの文法、条件式 - 続き
4. 配列について
5. ハッシュ配列について
6. 関数について
7. 関数について - 続き
8. 文字列操作関数
9. 配列操作関数
10. ファイル操作
11. ファイル操作 - 続き
12. パラメータの受け渡し
13. クッキーとセッション
14. 総合練習
15. メール送信
16. ファイルアップロード
17. クラスについて
18. クラスについて - 続き
19. MySQL
20. MySQL - 続き(1)
21. MySQL - 続き(2)
22. PostgreSQL
23. 総合練習
24. 総合練習解答



8. 文字列操作関数

今日は、文字列操作関数について、ご説明いたします。

■文字列操作の関数
以前、文字列の結合や判定方法をご紹介しましたが、それに加え、文字列を自在に
操作するPHP関数を一部ご紹介します。

strtolower($str)
アルファベットの大文字を小文字に変換します。
strtoupper($str)
アルファベットの小文字を大文字に変換します。
strlen($str) 文字列$strのバイト数を返します。
substr($str, $num1, $num2)
文字列$strの$num1番目から、$num2の長さ分切り出します。
strpos($str1, $str2)
文字列$str1の中から最初の$str2を検索し、位置を返します。
strrpos($str1, $str2)
文字列$str1の中から最後の$str2を検索し、位置を返します。
str_replace($old, $new, $str)
文字列$str内の文字$oldを$newに変換します。
sprintf($format, $str1, $str2, $str3, ・・・)
指定した書式にフォーマットします。

大体この辺りがよく使用する文字列操作関数ですが、PHPにはこの他たくさんの
文字列操作関数が用意されています。興味があれば、ご自分で調べてみてください。

また、PHPには日本語の文字列を操作するマルチバイト文字列関数というものも
用意されており、日本語の文字列操作をする場合は、こちらを使用した方が
安全と言えます。

例えば、mb_strlen関数は、日本語の 2バイトも 1文字としてカウントしますので、
バイト数ではなく、文字数を返してくれます。

しかし、サーバによっては、マルチバイト文字列関数が使用できない場合も
ありますので、注意が必要です。

以下にサンプルを記述します。

-----------------------------------------------------------------
$a = "ABc";

// 文字列を小文字に変換
$a = strtolower($a);
print $a;

// 文字列を大文字に変換
$a = strtoupper($a);
print $a;

// 文字列のサイズを取得
print strlen($a);

// 文字列の切り出し
$str1 = "This is a test.";
$str2 = substr($str1, 10, 4);
print $str2;

// 文字列の検索
print strpos($str1, "is");
print strrpos($str1, "is");

// 文字列の置換
$str1 = str_replace("test", "sample", $str1);
print $str1;

$year = 1999;
$mon = 1;
$mday = 1;
$hour = 15;
$min = 30;
$sec = 0;

# 文字列をフォーマット
$str3 = sprintf("%4d/%02d/%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
print $str3;
-----------------------------------------------------------------

先ほども言いましたが、strlen()はバイト数が返ってくるので、文字数とは
違います。日本語などの全角の文字は 1 文字 2 バイトです。
例えば、

$a = "テスト";
print strlen($a);

の場合は、6 が返ってきます。

substr()は、最初の文字から切り出す場合、0 から始まることに注意してください。
3 つ目の引数は、切り出す長さを指定します。

strpos()は、文字列検索です。上のサンプル場合、"is"を先頭から検索し、位置を
返します。この位置も、0 番目から数えた値になります。

strrpos()は、文字列を逆から検索します。上のサンプルでは、"is"が 2 箇所ある
ので、後ろにある"is"の位置が返ってきます。また、この場合の戻り値も、先頭の
0 番目から数えた値になります。

str_replace()は、文字列の置換を行います。第一引数が検索する文字列、第二
引数が置き換える文字列、第三引数が、置換対象となる文字列になります。

次に、sprintf()ですが、まず、一番目の引数に、出力したいフォーマットの
文字列を渡します。

ここで、%4dや、%02dなどがありますが、こちらを簡単にご説明します。

%dと記述すると、数字を文字列にしていると考えてください。例えば、

sprintf("%d", 4);

とするだけで、文字列の"4"が返ります。

%2dと記述すると、整数の 2 桁を文字列に変換することになります。例えば、

sprintf("%2d", 4);

とすると、" 4"が返ります。桁数が多くても、切り捨てられることはないようです。

%02dと記述すると、桁数が少ない場合に、前に 0 を付けます。例えば、

sprintf("%02d", 4);

とすると、"04"が返ります。

また、一気に文字列フォーマットを作成する場合は、

sprintf("%04d/%02d/%02d", $year, $mon, $mday);

のように記述すれば、第二引数以降、順番に出力されます。

他にも書式はありますが、とりあえずこのくらいを覚えておけば十分です。

■パターンマッチ
ある特定の文字を検索したい場合、正規表現関数というものを使用します。

ereg($pattern, $str)

これは、文字列$strが$patternに一致しているかの判定で使用します。
例えば、数値チェックや、メールアドレスの形式チェックなどでよく使います。

実際には、

-----------------------------------------------------------------
$a = "http://www.google.co.jp/";
if (ereg("http://www\.", $a)) {
print "Matched.";
}
-----------------------------------------------------------------

のように使用します。

上のサンプルは、"http://www."という文字列にマッチしているかを検索して
います。

"."は特殊文字になりますので、文字として扱う場合は、"\"が必要です。

ereg()の第一引数の記述方法は、かなり特殊なものになります。

以下に、使用頻度が高いものをまとめて記述します。

●メタ文字

. 改行を除く任意の 1 文字
* 0 回以上のパターン繰り返し
+ 1 回以上のパターン繰り返し
? 0 または 1 回のパターン
^ 先頭から
$ 末尾から
\ メタ文字エスケープ
| パターン論理和
() パターングループ
[] 文字クラス
{} 量指定子

\n 改行
\r キャリッジリターン
\f ラインフィード
\t タブ
\d 数字 [0-9]
\D 数字以外 [^0-9]
\w 英数字単語 [_a-zA-Z0-9]
\W 英数字単語以外 [^_a-zA-Z0-9]
\s 空白 [ \t\n\r\f]
\S 空白以外 [^ \t\n\r\f]

ereg 関数群のホワイトスペースのマッチには、以下を使用するとのこと。

●文字クラス

- 範囲
^ 先頭に置くと検索文字以外にマッチ

[0123456789] 数字にマッチ
[0-9] 数字にマッチ(上と同じ)
[^0-9] 数字以外にマッチ
[a-zA-Z] 英字にマッチ

●量指定子

{}? 最短マッチ(? がないと最長マッチになる)

* 0 回以上のパターン繰り返し
+ 1 回以上のパターン繰り返し
? 0 または 1 回のパターン
{n}? n 回繰り返しマッチ
{n,}? n 回以上繰り返しマッチ
{n, m}? n 回以上、m 回以下繰り返しマッチ

以下に検索例を記述します。

-----------------------------------------------------------------
$rcd = ereg("abc", $var); abc にマッチ
$rcd = ereg("a.c", $var); a?c にマッチ
$rcd = ereg("a(bb|b1|b2)c", $var); abbc、ab1c、ab2c にマッチ
$rcd = ereg("^abc", $var); abc で始まるとマッチ
$rcd = ereg("abc$", $var); abc で終わるとマッチ
$rcd = ereg("^$", $var); 空行とマッチ
$rcd = ereg("ab?c", $var); ac、abc にマッチ
$rcd = ereg("a.*c", $var); ac、abc、ab1c などにマッチ
$rcd = ereg("a.+c", $var); abc、ab1c などにマッチ
$rcd = ereg("[0-9]{1, 2}", $var); 0 〜 99 にマッチ
$rcd = ereg("[a-zA-Z]{8,}", $var); 英字 8 文字以上にマッチ
$rcd = ereg("あいうえお{2}", $var); 「あいうえおお」にマッチ
$rcd = ereg("(あいうえお){2}", $var); 「あいうえおあいうえお」にマッチ
-----------------------------------------------------------------

また、ereg()関数は、大文字小文字を区別して検索しますが、区別しないで
検索する場合は、eregi()関数を使用します。使用方法は、ereg()と同じです。

全部のパターンは覚える必要はありません。必要な時に見るようにすれば十分です。

以下にサンプルを記述します。

-----------------------------------------------------------------
$a = "29307";
if (ereg("[0-9]", $a)) {
print "All number.";
}

$a = "This is a test.";
if (eregi("this.+test", $a)) {
print "Matched.";
}

$a = "39abc";
if (!ereg("^[0-9a-zA-Z]+$", $a)) {
print "Miss matched.";
}
-----------------------------------------------------------------

一番上は、数字のチェックを行っています。サンプルのように、"-"を使用すると、
どの文字からどの文字までを検索するという意味になります。この場合、[ ] で
くくります。

次のサンプルの".+"は、間に任意の文字が入るという意味になります。サンプルの
場合、大文字小文字の区別なしで、「this・・・testに一致する」という判定に
なります。

最後は、文字が一致しない場合の検索になります。サンプルの場合、半角英数字
以外の文字がある場合、if文は実行されないという処理になります。

 

★今日のまとめサンプルプログラム
-----------------------------------------------------------------
<HTML>
<BODY>
<?
$mail = 'TEST@homepage.co.jp';

// 小文字に変換
$mail = strtolower($mail);
print $mail . "<br>";

// 文字列のバイト数を表示
print "文字の長さは" . strlen($mail) . "バイトです。<br>";

// "@"の前の文字を取得
print "アカウントは" . substr($mail, 0, strpos($mail, '@')) . "<br>";

// "@"と"."が含まれているかの判定
if (ereg(".+@.+\..+", $mail) {
print "メールアドレスの形式です。<br>";
}

// .co.jpを.comに置換
$mail = str_replace(".co.jp", ".com", $mail);
print $mail . "<br>";

?>
</BODY>
</HTML>
-----------------------------------------------------------------

■解説
substr()関数の第三引数は、切り抜きする長さですから、0 番目から
strpos($mail, '@')で、"@"までを切り抜くことができます。

ereg()を使用すると、簡易的なメールチェックを行えます。サンプルでは、
「$mailに 〜@〜.〜 という文字が含まれている」という判定になります。
"."は特殊文字ですので、エスケープシーケンス"\"を付けます。

 

★課題
1. 以下の処理を行うプログラムを作成してください。

(1) 'test@homepage.co.jp'の文字列から、"@"と最初の"."の間の文字列を出力する
(2) 現在日時を取得し、'2004年01月01日 00時00分00秒'の形式で出力する
(3) 'abc123'という文字列が、半角アルファベットのみかどうかを判定する
(4) 'test'、'TEST'、'Test'のどの文字がきても、'Test'に置換して出力する
(strtolowerを使用)
(5) ある文字列の中に、'〜is〜sample〜'という形式に一致しているかを判定する
("〜"は任意の文字列とします)

 

★前回の課題の解答
1. 次の関数を作成し、別ファイルにまとめてパッケージ化してください。

(1) 2つの引数を受け取り、それぞれ 2で割った値を返す関数
(2) 3つの引数を受け取り、"・・・番目の引数は・・・"という文字列をそれぞれに
付け足して返す関数
(3) 現在日時を、"2005/01/01 23:00:00"というフォーマットで返す関数
(4) 現在の曜日を
('日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日')
のいずれかで返す関数
(5) 0 〜 9秒間、ランダムでプログラムが停止(スリープ)する関数

→下のサンプルを参照してください。

common.php
-----------------------------------------------------------------
<?

// (1) 2つの引数を受け取り、それぞれ 2で割った値を返す関数
function sub_1(&$a, &$b) {
$a /= 2;
$b /= 2;
}

// (2) 3つの引数を受け取り、"・・・番目の引数は・・・"という文字列をそれぞれに
// 付け足して返す関数
function sub_2(&$a, &$b, &$c) {
$a = "1番目の引数は" . $a;
$b = "2番目の引数は" . $b;
$c = "3番目の引数は" . $c;
}

// (3) 現在日時を、"2005/01/01 23:00:00"というフォーマットで返す関数
function sub_3() {
return date('Y/m/d H:i:s', time());
}

// (4) 現在の曜日を返す関数
function sub_4() {
$week = array('日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日');
return $week[date("w")];
}

// (5) 0 〜 9秒間、ランダムでプログラムが停止(スリープ)する関数
function sub_5() {
sleep(rand(0, 9));
}

?>
-----------------------------------------------------------------

index.php
-----------------------------------------------------------------
<HTML>
<BODY>
<?

require("./common.php");

// (1)
$a = 56;
$b = 82;

sub_1($a, $b);

print $a . "<br>" . $b;
print "<br>";

// (2)
$a = "TEST1";
$b = "TEST2";
$c = "TEST3";

sub_2($a, $b, $c);
print $a . "<br>" . $b . "<br>" . $c;
print "<br>";

// (3)
print sub_3();
print "<br>";

// (4)
print sub_4();
print "<br>";

// (5)
sub_5();

?>
</BODY>
</HTML>
-----------------------------------------------------------------

■解説
$a /= 2 は、 $a = $a / 2 と同じ意味ですね。引数に"&"をつけることで、参照
渡しとなり、呼び出し側にも反映されます。

曜日を取得する場合は、date("w")を使用します。

sleep関数は、しばらくプログラムを停止させる関数ですので、ランダムで
数秒止まったように見えますので、気をつけてください。




前の章へ 次の章へ


このエントリーをはてなブックマークに追加


OfficeLance

お問い合わせはこちらから