3

タイトルで申し訳ありませんが、これを言う方法が本当にわかりませんでした...

X 文字の後にカットする必要がある文字列がよくあります。私の問題は、この文字列に : & egrave ; などの特殊文字が含まれていることが多いことです。

それで、私が文字列を切断しているときに特別な文字の真ん中にいる場合、文字列を変換せずにPHPで知る方法はあるのだろうかと思っています。

This is my string with a special char : è - and I want it to cut in the middle of the "è" but still keeping the string intact

だから今、部分文字列での私の結果は次のようになります:

This is my string with a special char : &egra

しかし、私はこのようなものが欲しいです:

This is my string with a special char : è
4

6 に答える 6

7

ここで行う最善の方法は、文字列を html エンティティなしで UTF-8 として保存し、エンコーディングとしてmb_*関数のファミリを使用することです。utf8

ただし、文字列が ASCII または iso-8859-1/win1252 の場合HTML-ENTITIESは、mb_string ライブラリの特別なエンコードを使用できます。

$s = 'This is my string with a special char : è - and I want it to cut in the middle of the "è" but still keeping the string intact';
echo mb_substr($s, 0, 40, 'HTML-ENTITIES');
echo mb_substr($s, 0, 41, 'HTML-ENTITIES');

ただし、基になる文字列が UTF-8 またはその他のマルチバイト エンコーディングである場合、使用HTML-ENTITIES安全ではありません。これは、HTML-ENTITIES実際には「ハイビット文字を html エンティティとして使用する win1252」を意味するためです。これは、これがうまくいかない場合の例です。

// Assuming that é is in utf8:
mb_substr('é ', 0, 2, 'HTML-ENTITIES') === 'é'
// should be 'é '

文字列がマルチバイト エンコーディングの場合は、代わりに、分割する前にすべての html エンティティを共通のエンコーディングに変換する必要があります。例えば:

$strings_actual_encoding = 'utf8';
$s_noentities = html_entity_decode($s, ENT_QUOTES, $strings_actual_encoding); 
$s_trunc_noentities =  mb_substr($s_noentities, 0, 41, $strings_actual_encoding);
于 2012-07-24T19:10:37.407 に答える
3

最初にhtml_entity_decode()を使用して、すべてのHTMLエンティティをデコードできます。次に、文字列を分割します。次に、htmlentities()を使用してエンティティを再エンコードします。

$decoded_string = html_entity_decode($original_string);
// implement logic to split string here

// then for each string part do the following:
$encoded_string_part = htmlentities($split_string_part);
于 2012-07-24T18:55:19.343 に答える
3

最長のHTMLエンティティは、アンパサンドとセミコロンを含めて10文字の長さです。文字列をバイト単位でカットする場合は、XバイトをチェックX-9X-1てアンパサンドを確認します。対応するセミコロンがバイト以降に表示される場合は、バイトXの後ではなくセミコロンの後に文字列を切り取りますX

ただし、文字列を前処理する場合は、Mikeのソリューションは、文字列をバイトではなくX 文字でカットするため、より正確になります。

于 2012-07-24T18:57:04.240 に答える
3

最善の解決策は、テキストを HTML エンティティとして保存するのではなく、UTF-8 として保存することです。それ以外に、カウントがずれていてもかまわない場合 ( `7 ではなく 1 文字に等しい)、次のスニペットが機能するはずです。

<?php
$string = 'This is my string with a special char : &egrave; - and I want it to cut in the middle of the "&egrave;" but still keeping the string intact';
$cut_string = htmlentities(mb_substr(html_entity_decode($string, NULL, 'UTF-8'), 0, 45), NULL, 'UTF-8')."<br><br>";

注:別の関数を使用してテキストをエンコードする場合 (例: htmlspecialchars())、代わりにその関数を使用しますhtmlentities()html_entity_decode()カスタム関数を使用する場合は、代わりに新しいカスタム関数(およびの代わりにカスタム関数) の反対を行う別のカスタム関数を使用しますhtmlentities()

于 2012-07-24T19:04:12.193 に答える
2

ちょっとした力ずくの解決策ですが、式にあまり満足していません。PCREたとえば、80 文字を渡す必要があり、可能な限り長い HTML 式が 7 文字の長さであるとします。

$regex = '~^(.{73}([^&]{7}|.{0,7}$|[^&]{0,6}&[^;]+;))(.*)~mx'
// Note, this could return a bit of shorter text
return preg_replace( $regexp, '$1', $text);

ちょうどあなたが知っているので:

  • .{73}- 73文字
  • [^&]{7}- わかりました。 & を含まないもので埋めます。
  • .{0,7}$- 考えられる終わりを覚えておいてください (短いテキストはまったく一致しないため、これは必要ありません)。
  • [^&]{0,6}&[^;]+;- 最大 6 文字 (79 番目になります)、そして&終了させます

はるかに優れているように見えますが、数字を少し操作する必要があるのは、次のとおりです。

// check whether $text is at least $N chars long :)
if( strlen( $text) < $N){
    return;
}

// Get last &
$pos = strrpos( $text, '&', $N);

// We're not young anymore, we have to check this too (not entries at all) :)
if( $pos === false){
    return substr( $text, 0, $N);
}

// Get Last
$end = strpos( $text, ';', $N);

// false wouldn't be smaller then 0 (entry open at the beginning
if( $end === false){
    $end = -1;
}

// Okay, entry closed (; is after &)(
if( $end > $pos){
   return substr($text, 0, $N);
}

// Now we need to find first ;
$end = strpos( $text, ';', $N)
if( $end === false){
    // Not valid HTML, not closed entry, do whatever you want
}

return substr($text, 0, $end);

数値を確認してください。インデックスのどこかに +/-1 がある可能性があります...

于 2012-07-24T19:12:49.720 に答える
0

strpos と strrpos の組み合わせを使用して次のスペースと前のスペースを見つけ、スペース間のテキストを解析し、既知の特殊文字のリストと照合し、一致する場合は「カット」を次のスペースの位置。現在使用しているコード サンプルがあれば、より適切な回答を提供できます。

于 2012-07-24T18:54:49.567 に答える