次のコードは、CLI 経由で実行した場合と Apache/mod_php 経由で実行した場合で異なる結果をもたらします。
<pre>
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
echo setlocale(LC_ALL, 0)."\n";
// echo setlocale(LC_ALL, "en_GB.UTF-8")."\n";
$terms = array
(
//Always matches:
"Label Generation",
//Doesn't match when using u (PCRE_UTF8) modifier:
"Receipt of Prescription and Validation of Patient Information",
);
$text = "Some terms to match: ".implode(", ",$terms);
$pattern = "/(".implode(")|(", $terms).")/is";
$regexps = array
(
"Unicode" => $pattern."u", //Add u (PCRE_UTF8) modifier
"Non-unicode" => $pattern
);
echo "Text:\n'$text'\n";
foreach($regexps as $type=>$regexp)
{
$matches = array();
$total = preg_match_all($regexp,$text,$matches);
echo "\n\n";
echo "$type regex:\n'$regexp'\n\n";
echo "Total $type matches: ";
var_dump($total);
echo "\n$type matches: ";
var_dump($matches[0]);
}
?>
</pre>
CLI 出力 (正しい):
<pre>
/en_GB.UTF-8/C/C/C/C/C
Text:
'Some terms to match: Label Generation, Receipt of Prescription and Validation of Patient Information'
Unicode regex:
'/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/isu'
Total Unicode matches: int(2)
Unicode matches: array(2) {
[0]=>
string(16) "Label Generation"
[1]=>
string(61) "Receipt of Prescription and Validation of Patient Information"
}
Non-unicode regex:
'/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/is'
Total Non-unicode matches: int(2)
Non-unicode matches: array(2) {
[0]=>
string(16) "Label Generation"
[1]=>
string(61) "Receipt of Prescription and Validation of Patient Information"
}
</pre>
Apache/mod_php Web サーバーの結果 (正しくない - /u 修飾子を使用していない場合にのみ文字列に一致します):
/en_GB.ISO8859-1/C/C/C/C/C
Text:
'Some terms to match: Label Generation, Receipt of Prescription and Validation of Patient Information'
Unicode regex:
'/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/isu'
Total Unicode matches: int(1)
Unicode matches: array(1) {
[0]=>
string(16) "Label Generation"
}
Non-unicode regex:
'/(Label Generation)|(Receipt of Prescription and Validation of Patient Information)/is'
Total Non-unicode matches: int(2)
Non-unicode matches: array(2) {
[0]=>
string(16) "Label Generation"
[1]=>
string(61) "Receipt of Prescription and Validation of Patient Information"
}
/u (PCRE_UTF8) オプションを使用すると、Web サーバーは両方の文字列の照合に失敗します。setlocale(LC_ALL, "en_GB.UTF-8");
Web サーバーのロケールを CLI のロケールに一致させようとしましたが、これは正常に実行されましたが、出力には関係ありません。PCRE ライブラリに問題があるのではないかと疑っていますが、CLI と Web サーバーの間でどのように異なるのかわかりません - PHP は両方の環境で同じライブラリ バージョンを報告します: PHP 5.4.14 PCRE (Perl 互換正規表現) サポート => 有効PCRE ライブラリ バージョン => 8.32 2012-11-30
pcretest は UTF-8 サポートを報告していませんが、これにもかかわらず、CLI バージョンは正しい結果をもたらします
$> pcretest -C
PCRE version 8.32 2012-11-30
Compiled with
8-bit support
No UTF-8 support
No Unicode properties support
No just-in-time compiler support
Newline sequence is LF
\R matches all Unicode newlines
Internal link size = 2
POSIX malloc threshold = 10
Default match limit = 10000000
Default recursion depth limit = 10000000
Match recursion uses stack