PHP カーネル探索変数 - Extraordinary Strings_PHP チュートリアル

WBOY
リリース: 2016-07-13 09:58:47
オリジナル
656 人が閲覧しました

PHP カーネル探索変数 - 非自明な文字列

さあ、文字列について勉強しても良いことは何もありません。
そんなことは言わないで、「The Ordinary World」を見たことがありますか? 普通の文字列にも特別な物語がありえます。プレビュー:
(1) C 言語で、文字列を計算する strlen の時間計算量はどれくらいですか? PHPではどうなるでしょうか?
(2) PHP でマルチバイト文字列を処理するには? PHP の Unicode サポートはどうなっていますか?
これも文字列ですが、C 言語と C++/PHP/Java はなぜ違うのですか?
データ構造がアルゴリズムを決定します、この文はまったく真実です。
そこで今日は、PHP の文字列構造と関連する文字列関数の実装を見ていきます。
1. 文字列の基本
文字列は、PHP で最も頻繁に使用されるデータ構造の 1 つであると言えます (もう 1 つのより一般的に使用されるデータ構造は配列です。「変数 (4) - PHP カーネル探索における配列操作」を参照してください)。 PHP 言語の特性とアプリケーション シナリオにより、私たちの日常タスクの多くは実際に文字列を処理します。このため、PHP は開発者に豊富な文字列操作関数を提供しています (予備統計によると、その数は約 100 で、これはかなりの数です)。では、PHP では文字列はどのように実装されるのでしょうか? C言語との違いは何ですか?
1. PHPにおける文字列の表現
PHP では文字列を使用する一般的な形式が 4 つあります:
(1) 二重引用符
この形式がより一般的です: $str=”this is
(2) シングルクオート
一重引用符で囲まれた文字は未処理とみなされ、一重引用符で囲まれた変数、制御文字などは解析されません。
$string = "テスト";
$str = 'これは $string です、あはん';
エコー $str;
(3) ヒアドキュメント
Heredoc は、より長い文字列表現に適しており、複数行の文字列表現にはより柔軟で多用途です。二重引用符表現と同様に、ヒアドキュメントに変数を含めることもできます。一般的な形式は次のとおりです:
$string="テスト文字列";
$str = <<
これは文字列nです
私の文字列は $string です
STR;
エコー $str;
(4) nowdoc (5.3+ サポート)
nowdoc と Heredoc は非常に似ているので、兄弟のように考えることができます。 nowdoc の開始識別子は一重引用符で囲まれています。一重引用符と同様に、変数やフォーマット制御文字などは解析されません。
$s = <<<'EOT'
これは $str です
これはテストです;
EOT;
エコー$s;
2. PHP の文字列の構造
前述したように、PHP の変数は Zval (PHP カーネル探索変数 (1) Zval) のような構造体を使用して格納されます。 Zval の構造は次のとおりです:
struct _zval_struct {
zvalue_value 値 /* 値 */
zend_uint refcount__gc; /* 変数の参照カウント */
zend_uchar タイプ; /* アクティブなタイプ */
zend_uchar is_ref__gc; /* ref 変数の場合 */
};
そして、変数の値は zvalue_value のような共用体です:
typedef Union _zvalue_value {
長いlval;
ダブル dval;
struct { /* 文字列 */
char *val;
int len;
} ストラ;
ハッシュテーブル *ht;
zend_object_value obj;
}zvalue_value;
そこから文字列の構造を抽出します:
構造体{
char *val;
int len;
}
PHP の文字列は、実際には文字列へのポインタと文字列の長さを含む最下位レベルの構造体であることが明らかになりました。
それで、なぜこんなことをするのですか?言い換えれば、これを行うことでどのようなメリットがあるのでしょうか?次に、PHP 文字列と C 言語文字列を比較して、このような構造を使用して文字列を格納する利点を説明します。
3. C言語の文字列との比較
C 言語では、文字列は 2 つの一般的な形式で格納できることがわかっています。1 つはポインターを使用し、もう 1 つは文字配列を使用します。次の手順では、C 言語の文字配列を使用して文字列を格納します。
(1) PHP 文字列はバイナリ セーフですが、C 文字列はバイナリ セーフではありません。
「バイナリ セキュリティ」という用語がよく出てきますが、バイナリ セキュリティとは正確には何を意味するのでしょうか?
Wikipedia での Binary Safe の定義は次のとおりです:
バイナリセーフとは、主に文字列操作関数に関連して使用されるコンピューター プログラミング用語です。
バイナリセーフ関数とは、本質的に、入力を特定の形式を持たないデータの生のストリームとして扱う関数です。
したがって、文字が取り得る 256 個のすべての値で動作するはずです (8 ビット文字を想定)。
訳:
バイナリ セーフティは、主に文字列操作関数に使用されるコンピューター プログラミング用語です。バイナリ セーフ関数とは、基本的に、入力を特別なフォーマットを行わずに生のデータ ストリームとして扱うことを意味します。
では、なぜ C 文字列はバイナリセーフではないのでしょうか? C 言語では、文字配列で表される文字列は常に次で終わることが知られています。
(2) 効率の比較。
C文字列で使用されているため
構造体{
char *val;
int len;
}
このような構造で表されるため、文字列の長さの取得は定数時間で完了できます:
#define Z_STRLEN(zval) (zval).value.str.len
もちろん、strlen 関数のパフォーマンスだけでは、「PHP の文字列は C 文字列より効率的である」という結論を裏付けることはできません (明らかな理由は、PHP が C 言語をベースに構築された高級言語であるためです)。 、時間の複雑さの点では、PHP 文字列は C 文字列よりも効率的です。
(3) 多くの C 文字列関数にはバッファ オーバーフローの脆弱性があります
バッファ オーバーフローは C 言語の一般的な脆弱性であり、このセキュリティ リスクは多くの場合致命的です。バッファ オーバーフローの典型的な例は次のとおりです:
void str2Buf(char *str) {
文字バッファ[16];
strcpy(buffer,str);
}
この関数は str の内容をバッファ配列にコピーします。バッファ配列のサイズは 16 であるため、str の長さが 16 より大きい場合、バッファ オーバーフローの問題が発生します。
strcpy に加えて、gets、strcat、fprintf などの文字列関数にもバッファ オーバーフローの問題があります。
PHP には strcpy や strcat などの関数はありません。実際、PHP 言語は単純であるため、strcpy や strcat などの関数を提供する必要はありません。たとえば、文字列をコピーしたい場合は、=: を使用するだけです
$str = "これは文字列です";
$str_copy = $str;
PHP の zval を共有する変数の特性により、スペースの無駄がなく、簡単に文字列接続を実現できます。
$str = "これは";
$str .= "テスト文字列";
エコー $str;
文字列連結プロセス中のメモリ割り当てと管理については、zend エンジン部分の実装を確認できますが、ここでは今のところ無視されています。
2.文字列操作関連関数(一部)
文字列を勉強する目的は、その構造や特性を知ることだけではなく、より良く使用することであることに疑いの余地はありません。私たちの日常業務では、日付文字列の処理、パスワードの暗号化、ユーザー情報の取得、正規表現の一致と置換、文字列の置換、文字列の書式設定など、ほとんどの作業に文字列の処理が含まれます。 PHP 開発では、(呼吸から逃れられないのと同じように) 文字列との直接的または間接的な接触を避けることはできないと言えます。このため、PHP は開発者に、文字列操作の 90% 以上に適した豊富な文字列操作関数 (http://cn2.php.net/manual/en/ref.strings.php) を多数提供しています。 , 基本的には十分です。
文字列関数は非常に多くあるため、1 つずつ説明するのは不可能です。ここでは、簡単に説明するために、いくつかの典型的な文字列操作関数のみを選択します (PHPer の 80% 以上は文字列操作関数をよく理解していると思います)。
説明を始める前に、文字列関数の使用原則を理解して習得することが、文字列関数を効率的かつ熟練的に使用するために非常に重要です。
(1) 操作で正規表現または文字列を使用できる場合。次に、文字列操作に優先順位を付けます。
正規表現は、テキストを処理するための優れたツールであり、特にパターン検索やパターン置換などのアプリケーションにとっては無敵であると言えます。このため、正規表現は多くの状況で誤用されます。文字列関数または正規表現を使用して文字列操作を完了できる場合は、正規表現は特定の状況でパフォーマンスに重大な問題を引き起こす可能性があるため、文字列操作関数を優先してください。
(2) false と 0 に注意してください
PHPは弱い変数型で、最初は多くのphperが苦労したと思います
var_dump( 0 == false);//bool(true)
var_dump( 0 === false);//bool(false)
ちょっと待って、これは文字列操作関数と何の関係があるのですか?
PHP には、検索に使用される関数の一種 (strpos、stripos など) があり、検索が成功すると、この種の検索関数は strpos のように、元の文字列内の部分文字列のインデックスを返します。
var_dump(strpos("これは abc", "abc"));
検索が失敗した場合は false が返されます:
var_dump(strpos("これは abc", "角度"));//false
ここには落とし穴があります。文字列のインデックスも 0 から始まります。部分文字列がたまたまソース文字列の先頭に現れた場合、単純な == 比較では strpos が成功したかどうかを区別できません。
var_dump(strpos("これは abc", "これ"));
したがって、比較するには === を使用する必要があります:
if((strpos("これは abc", "これ")) === false){
// 見つかりません
}
(3) 車輪の再発明を避けるために、マニュアルをもっと読みましょう。
多くの PHPer インタビューで次の質問に遭遇したと思います: 文字列を反転するにはどうすればよいですか?質問には「方法」のみが記載されているため、「PHP 組み込み関数を使用しない」という制限はありません。したがって、この質問の場合、最も簡単な方法は当然 strrev 関数を使用することです。車輪の再発明をすべきではないことを示すもう 1 つの関数は、levenshtein 関数です。その名前が示すように、この関数は 2 つの文字列間の編集距離を返します。編集は動的計画法(DP)の代表的な事例の一つとして、多くの人に馴染みがあると思います。このような問題が発生した場合でも、DP を開始する準備はできていますか? 1 つの関数でそれを実行します:
$str1 = "これはテストです";
$str2 = "彼はテスです";
エコー レーベンシュタイン($str1, $str2);
私たちは皆、特定の状況ではできるだけ「怠惰」であるべきですよね?
以下は文字列操作関数の抜粋です(最も一般的な操作についてはマニュアルを直接参照してください)
1.strlen
このタイトルが出た瞬間、ほとんどの人はこんな表情をしたのではないでしょうか
または次のようにします:
私が言いたいのは関数そのものではなく、この関数の戻り値です。
int strlen (文字列 $string)
指定された文字列の長さを返します。
マニュアルには「strlen関数は指定された文字列の長さを返す」と明記されていますが、長さの単位が「文字数」または「文字のバイト数」を指すのかについては説明がありません。 。私たちがしなければならないのは推測することではなく、テストすることです:
GBK エンコード形式の場合:
echo strlen("これは中国語です") //8
;
strlen関数が文字列のバイト数を返すという説明。次に、別の問題が発生します。utf-8 エンコードの場合、中国語は utf8 エンコードで 3 バイトを使用するため、期待される結果は 12:
になります。
echo strlen("これは中国語です") //12
;
これは、strlen による文字列の長さの計算は現在のエンコード形式に依存し、その値は一意ではないことを意味します。場合によっては、これでは当然満足できない場合もあります。現時点では、マルチバイト拡張 mbstring には再生する余地があります:
echo mb_strlen("これは中国語です", "GB2312");//4
この点については、マルチバイト処理で対応する説明があるので、ここでは省略します。
2. str_word_count
str_word_count も比較的強力で無視しやすい文字列関数です。
mixed str_word_count ( string $string [, int $format = 0 [, string $charlist ]] )
$format の値が異なると、str_word_count 関数の動作が異なる可能性があります。 今、このテキストが手元にあります:
落ち込んでいて、ああ、心がとても疲れているとき
困難が来て心に負担がかかるとき
それでは、私はここで静寂の中でじっと待っています
あなたが来て、しばらく私と一緒に座るまで
あなたが私を育ててくれたので、私は山の上に立つことができます
あなたは嵐の海を歩けるように私を育ててくれます
あなたの肩に乗ると私は強いです
あなたは私を育ててくれます…私ができる以上のものに
あなたが私を育ててくれたので、私は山の上に立つことができます
あなたは嵐の海を歩けるように私を育ててくれます
あなたの肩に乗ると私は強いです
あなたは私を育てて、私ができる以上のものにします。
その後:
(1)$format = 0
$format=0、$format はテキスト内の単語数を返します:
echo str_word_count(file_get_contents(“単語”)); //112
(2)$format = 1
$format=1 の場合、テキスト内のすべての単語の配列が返されます:
print_r(file_get_contents(“単語”),1 );
配列
(
[0] => いつ
[1] => 私
[2] => 午前
[3] => 下へ
[4] => そして
[5] => ああ
[6] => 私の
[7] => 魂
[8] => そう
[9] => 疲れた
[10] => いつ
[11] => トラブル
......
)
この機能は何をするのですか?たとえば、英語の分詞。 「単語数」の問題を覚えていますか? str_word_count は単語統計の TopK 問題を簡単に完了できます:
$s = file_get_contents("./word");
$a = array_count_values(str_word_count($s, 1)) ;
arsort( $a );
print_r( $a );
/*
配列
(
[私]=>10
[私] => 7
[レイズ] => 6
[上] => 6
[あなた] => 6
[午前] => 6
[オン] => 6
[できる] => 4
[そして] => 4
[be] => 3
[だから] => 3
……
);*/
(3)$format = 2
$format=2 の場合、連想配列が返されます:
$a = str_word_count($s, 2);
print_r($a);
/*
配列
(
[0] => いつ
[5] => 私
[7] => 午前
[10] => 下へ
[15] => そして
[20] => ああ
[23] => 私の
[26] => 魂
[32] => だから
[35] => 疲れた
[41] => いつ
[46] => トラブル
[55] => 来てください
...
)*/
他の配列関数を使用すると、より多様な関数を実現できます。たとえば、array_flip を使用すると、単語の最後の出現位置を計算できます。
$t = array_flip(str_word_count($s, 2));
print_r($t);
そして、array_unique と array_flip を組み合わせると、単語が最初に出現する位置を計算できます:
$t = array_flip( array_unique(str_word_count($s, 2)) );
print_r($t);
配列
(
[いつ] => 0
[私]=>5
[午前] => 7
[下] => 10
[そして] => 15
[ああ] => 20
[私] => 23
[魂] => 26
[だから] => 32
[疲れた] => 35
[トラブル] => 46
[来て] => 55
[ハート] => 67
...
)
3. 類似テキスト
これは、levenshtein() 関数に加えて 2 つの文字列の類似性を計算する別の関数です:
int like_text ( string $first , string $sec [, float &$percent ] )
$t1 = 「あなたが私を育ててくれたので、私は山の上に立つことができます。」;
$t2 = "嵐の海の上を歩けるように、あなたは私を育ててくれます";
$パーセント = 0;
echo minimum_text($t1, $t2, $percent).PHP_EOL;//26
エコー $パーセント;// 62.650602409639
具体的な使用法とは別に、文字列の根本的な類似性がどのように定義されているかに興味があります。
Similar_text 関数の実装は ext/standard/string.c にあり、そのキーコードを抜粋します:
PHP_FUNCTION(similar_text){
文字 *t1、*t2;
zval **パーセント = NULL;
int ac = ZEND_NUM_ARGS();
int sim;
int t1_len、t2_len;
/* パラメータ分析 */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Z", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) {
戻る;
}
/* パーセントを double 型に設定します */
if (ac > 2) {
Convert_to_double_ex(パーセント);
}
/* t1_len == 0 && t2_len == 0 */
if (t1_len + t2_len == 0) {
if (ac > 2) {
Z_DVAL_PP(パーセント) = 0;
}
RETURN_LONG(0);
}
/* 同一の文字列の数を数える */
sim = php_similar_char(t1, t1_len, t2, t2_len);
/* 類似率 */
if (ac > 2) {
Z_DVAL_PP(パーセント) = sim * 200.0 / (t1_len + t2_len);
}
RETURN_LONG(シム);
}
類似する文字列の数は php_similar_char 関数を通じて取得され、類似性のパーセンテージは次の式によって取得されることがわかります:
パーセント = sim * 200 / (t1 文字列長 + t2 文字列長)
を定義します。
php_similar_char の具体的な実装:
static int php_similar_char(const char *txt1, int len1, const char *txt2, int len2)
{
合計;
int pos1 = 0、pos2 = 0、最大;
php_similar_str(txt1, len1, txt2, len2, &pos1, &pos2, &max);
if ((sum = max)) {
if (pos1 && pos2) {
sum += php_similar_char(txt1, pos1,txt2, pos2);
}
if ((pos1 + max
sum += php_similar_char(txt1 + pos1 + max, len1 - pos1 - max,txt2 + pos2 + max, len2 - pos2 - max);
}
}
返金額;
}
この関数は、php_similar_str を呼び出すことで類似する文字列の数の統計を完了し、php_similar_str は文字列 s1 と文字列 s2 の間で同一の最長の文字列長を返します。
static void php_similar_str(const char *txt1, int len1, const char *txt2, int len2, int *pos1, int *pos2, int *max)
{
char *p、*q;
char *end1 = (char *) txt1 + len1;
char *end2 = (char *) txt2 + len2;
int l;
*最大 = 0;
/* 最長の文字列を検索します */
for (p = (char *) txt1; p < end1; p++) {
for (q = (char *) txt2; q for (l = 0; (p + l if (l > *max) {
*max = l;
*pos1 = p - txt1;
*pos2 = q - txt2;
}
}
}
}
php_similar_str のマッチングが完了すると、元の文字列は 3 つの部分に分割されます:
最初の部分は最長の文字列の左側の部分です。この部分には同様の文字列が含まれていますが、最長ではありません。
2 番目の部分は、最も長い同様の文字列部分です
3 番目の部分は、最も長い文字列の右側の部分です。最初の部分と同様に、この部分には同様の文字列が含まれていますが、最も長い部分ではありません。したがって、最初と 3 番目の部分の類似した文字列の長さを再帰的に見つける必要があります:
/* 最長の文字列の左側にある類似の文字列 */
if (pos1 && pos2) {
合計 += php_similar_char(txt1, pos1,txt2, pos2);
}
/* 右半分に同様の文字列 */
if ((pos1 + max
sum += php_similar_char(txt1 + pos1 + max, len1 - pos1 - max, txt2 + pos2 + max, len2 - pos2 - max);
}
マッチングプロセスを以下の図に示します:
文字列関数の詳細については、PHP オンライン マニュアルを参照してください。ここでは説明しません。
3. マルチバイト文字列
これまで説明してきた文字列と関連する演算関数はすべてシングルバイトです。しかし、赤いスイカや黄色いスイカがあるように、世界はとてもカラフルで、ストリングスも例外ではありません。たとえば、一般的に使用される漢字を GBK でエンコードする場合、実際には 2 バイトを使用してエンコードされます。マルチバイト文字列には中国語の文字に限定されず、日本語、韓国語、その他多くの国の文字も含まれます。このため、マルチバイト文字列の処理は非常に重要です。
文字と文​​字セットは、プログラミングの過程で必ず出てくる用語です。このセクションの内容が特によくわからないお子様がいる場合は、「エンコーディング メジャー 1 文字エンコーディングの基礎 - 文字と文​​字セット」に進むことをお勧めします
私たちは日常生活で中国語を使用することが多いため、中国語の文字列インターセプトを例として取り上げ、中国語の文字列の問題に焦点を当てます。
中国語の文字列インターセプト 中国語の文字列インターセプトは常に比較的厄介な問題です。その理由は次のとおりです。
(1) PHP のネイティブ substr 関数は、シングルバイト文字列のインターセプトのみをサポートし、マルチバイト文字列に対してはわずかに非力です
(2) PHP 拡張機能 mbstring にはサーバーのサポートが必要です。実際、多くの開発環境では mbstring 拡張機能が有効になっていません。これは、mbstring 拡張機能の使用に慣れている子供にとっては残念です。
(3) さらに複雑な問題は、UTF-8 エンコーディングの場合、中国語は 3 バイトですが、中国語の一部の特殊文字 (キャレット · など) は実際には 2 バイト エンコーディングであることです。これにより、間違いなく中国語の文字列を傍受することがより困難になります (結局のところ、中国語の文字列に特殊文字がまったく含まれないことは不可能です)。
頭が痛いことに加えて、中国語の文字列インターセプト ライブラリを構築する必要があります。この文字列インターセプト関数には、substr と同様の関数パラメーター リストがあり、中国語の GBK エンコーディングと UTF-8 エンコーディングでのインターセプトをサポートする必要があります。効率を高めるため、サーバーが mbstring 拡張機能を有効にしている場合は、mbstring の文字列インターセプトを直接使用する必要があります。
API:
String cnSubstr(string $str, int $start, int $len, [$encode=’GBK’]);//パラメータの $start と $len はバイト数ではなく文字数であることに注意してください。
UTF-8 エンコーディングで中国語をインターセプトするというアイデアを説明するために、UTF-8 エンコーディングを例に挙げます。
(1)コーディング範囲:
UTF-8 エンコード範囲 (utf-8 は文字のエンコードに 1 ~ 6 バイトを使用しますが、実際に使用されるのは 1 ~ 4 バイトのみです):
1バイト: 00——7F
2バイト: C080——DFBF
3 文字: E08080——EFBFBF
4 文字: F0808080——F7BFBFBF
これによれば、文字が占めるバイト数は最初のバイトの範囲に基づいて決定できます。
$ord = ord($str{$i});
$ord
192
224
中国語には4バイト文字はありません
(2) $startがマイナスの場合
if( $start
$start += cnStrlen_utf8( $str );
if( $start
$start = 0;
}
}
インターネット上のほとんどの文字列インターセプト バージョンは、$start
ここで、cnStrlen_utf8 は、utf8 エンコーディングでの文字列の文字数を取得するために使用されます。
関数 cnStrlen_utf8( $str ){
$len = 0;
$i = 0;
$slen = strlen( $str );
while( $i < $slen ){
$ord = ord( $str{$i} );
if( $ord
$i ++;
}else if( $ord
$i += 2;
}その他{
$i += 3;
}
$len ++;
}
$len を返します;
}
UTF-8 のインターセプトアルゴリズムは次のとおりです:
関数 cnSubstr_utf8( $str, $start, $len ){
if( $start
$start += cnStrlen_utf8( $str );
if( $start
$start = 0;
}
}
$slen = strlen( $str );
if( $len
$len += $slen - $start;
if($len
$len = 0;
}
}
$i =
;
$count = 0;
/* 開始位置を取得 */
while( $i < $slen && $count < $start){
$ord = ord( $str{$i} );
if( $ord
$i ++;
}else if( $ord
$i += 2;
}その他{
$i += 3;
}
$count ++;
}
$count = 0;
$substr = '';
/* $len 文字をインターセプト */
while( $i
$ord = ord( $str{$i} );
if( $ord
$substr .= $str{$i};
$i ++;
}else if( $ord
$substr .= $str{$i};
$i += 2;
}その他{
$substr .= $str{$i+1};
$i += 3;
}
$count ++;
}
$substr;を返します
}
最終的な cnSubstr() は次のように設計できます (プログラムにはまだ最適化の余地がたくさんあります):
function cnSubstr( $str, $start, $len, $encode = 'gbk' ){
if( extension_loaded("mbstring") ){
// echo "mbstring を使用";
//return mb_substr( $str, $start, $len, $encode );
}
$enc = strto lower( $encode );
スイッチ($enc){
ケース「gbk」:
ケース「gb2312」:
return cnSubstr_gbk($str, $start, $len);
休憩;
ケース「utf-8」:
ケース「utf8」:
return cnSubstr_utf8($str, $start, $len);
休憩;
デフォルト:
// 何らかの警告を行うか、エラーをトリガーします。
}
}
簡単にテストしてみましょう:
$str = "これは中国語の文字列 string であり、abs· ";
for($i = 0; $i
echo cnSubstr( $str, $i, 3, 'utf8').PHP_EOL;
}
最後に、ThinkPHP extend で提供される msubstr 関数を投稿します (これは正規表現で作成された substr です):
関数 msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
if(function_exists("mb_substr"))
$slice = mb_substr($str, $start, $length, $charset);
elseif(function_exists('iconv_substr')) {
$slice = iconv_substr($str,$start,$length,$charset);
if(false === $slice) {
$slice = '';
}
}その他{
$re['utf-8'] = "/[x01-x7f]|[xc2-xdf][x80-xbf]|[xe0-xef][x80-xbf]{2}|[xf0-xff][ x80-xbf]{3}/";
$re['gb2312'] = "/[x01-x7f]|[xb0-xf7][xa0-xfe]/";
$ re ['gbk'] '$ Re [' Big5 '] = "/[x01-X7F] | [x81-xfe] ([x40-x7e] | xa1-xfe]/")/"
preg_match_all($re[$charset], $str, $match);
$slice = join("",array_slice($match[0], $start, $length));
}
$slice を返しますか?'...' : $slice;
}
記事が長いため、他にも質問がありますが、ここでは詳しく説明しません。改めて、ご質問等ございましたら、お気軽にご指摘ください。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/976800.html技術記事 PHP カーネルで調査される変数 - 重要な文字列の切断、文字列について何を学ぶべきか。 そんなことは言わないで、「The Ordinary World」を見たことはありますか?
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート