PHPで記述されたコードスニペットを使用して、データベースからテキストのブロックをプルし、それをWebページのウィジェットに送信します。テキストの元のブロックは、長い記事でも短い文でも2つでもかまいません。しかし、このウィジェットでは、たとえば200文字を超えることはできません。substr()を使用してテキストを200文字で切り取ることができますが、結果は単語の途中で途切れるでしょう-私が本当に欲しいのは、200文字の前の最後の単語の終わりでテキストを切り取ることです。
PHPで記述されたコードスニペットを使用して、データベースからテキストのブロックをプルし、それをWebページのウィジェットに送信します。テキストの元のブロックは、長い記事でも短い文でも2つでもかまいません。しかし、このウィジェットでは、たとえば200文字を超えることはできません。substr()を使用してテキストを200文字で切り取ることができますが、結果は単語の途中で途切れるでしょう-私が本当に欲しいのは、200文字の前の最後の単語の終わりでテキストを切り取ることです。
回答:
ワードラップ機能を使用する。最大幅が指定した幅になるようにテキストを複数行に分割し、単語の境界で分割します。分割後、最初の行を取得するだけです。
substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));
このonelinerが処理しない1つのことは、テキスト自体が目的の幅より短い場合です。このエッジケースを処理するには、次のようにする必要があります。
if (strlen($string) > $your_desired_width)
{
$string = wordwrap($string, $your_desired_width);
$string = substr($string, 0, strpos($string, "\n"));
}
上記のソリューションでは、実際のカットポイントの前に改行が含まれていると、テキストが途中でカットされるという問題があります。この問題を解決するバージョンは次のとおりです。
function tokenTruncate($string, $your_desired_width) {
$parts = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
$parts_count = count($parts);
$length = 0;
$last_part = 0;
for (; $last_part < $parts_count; ++$last_part) {
$length += strlen($parts[$last_part]);
if ($length > $your_desired_width) { break; }
}
return implode(array_slice($parts, 0, $last_part));
}
また、実装のテストに使用されたPHPUnit testclassは次のとおりです。
class TokenTruncateTest extends PHPUnit_Framework_TestCase {
public function testBasic() {
$this->assertEquals("1 3 5 7 9 ",
tokenTruncate("1 3 5 7 9 11 14", 10));
}
public function testEmptyString() {
$this->assertEquals("",
tokenTruncate("", 10));
}
public function testShortString() {
$this->assertEquals("1 3",
tokenTruncate("1 3", 10));
}
public function testStringTooLong() {
$this->assertEquals("",
tokenTruncate("toooooooooooolooooong", 10));
}
public function testContainingNewline() {
$this->assertEquals("1 3\n5 7 9 ",
tokenTruncate("1 3\n5 7 9 11 14", 10));
}
}
'à'のような特別なUTF8文字は処理されません。REGEXの最後に「u」を追加して処理します。
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);
\n
、希望する幅の前にaがある場合、テキストを途中でカットするようです。
Arabic
文字とそのの助けを借りて、今正しい言葉に減少tokenTruncate
TNX万人:) ..機能
これは、単語の最初の200文字を返します。
preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));
if (strlen($string) > $your_desired_width) { preg_replace(...); }
/\s+?(?:\S+)?$/
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));
そして、あなたはそれを持っています—最大の文字列の長さを維持しながら、任意の文字列を最も近い完全な単語に切り捨てる信頼できる方法。
上記の他の例を試しましたが、望ましい結果が得られませんでした。
if
声明:if (strlen($str) > 200) { ... }
$WidgetText = substr($string, 0, strpos($string, ' ', 200));
次の解決策は、wordwrap関数の$ breakパラメータに気付いたときに生まれました。
string wordwrap(string $ str [、int $ width = 75 [、string $ break = "\ n" [、bool $ cut = false]]])
これが解決策です:
/**
* Truncates the given string at the specified length.
*
* @param string $str The input string.
* @param int $width The number of chars at which the string will be truncated.
* @return string
*/
function truncate($str, $width) {
return strtok(wordwrap($str, $width, "...\n"), "\n");
}
例1。
print truncate("This is very long string with many chars.", 25);
上記の例は出力します:
This is very long string...
例2。
print truncate("This is short string.", 25);
上記の例は出力します:
This is short string.
description
、ブログ投稿のを抽出しようとしている場合)、これは機能しません
preg_replace('/\s+/', ' ', $description)
すべての空白文字を単一のスペースに置き換えるために常に前処理を行うことができます;)
中国語や日本語などの一部の言語では単語を分割するためにスペース文字を使用しないので、「単語」で分割するときは常に注意してください。また、悪意のあるユーザーは、スペースを入れずにテキストを入力したり、標準のスペース文字に似たUnicodeを使用したりすることができます。この場合、使用するソリューションによって、とにかくテキスト全体が表示される可能性があります。これを回避する方法は、通常のようにスペースで分割した後、文字列の長さを確認することです。その後、文字列が依然として異常な制限(この場合は225文字)を超えている場合、先に進んでその制限でばかげて分割します。
非ASCII文字に関しては、このようなことに関するもう1つの警告があります。それらを含む文字列は、PHPの標準strlen()によって実際よりも長いものとして解釈される場合があります。これは、1つの文字が1バイトではなく2バイト以上かかる場合があるためです。strlen()/ substr()関数を使用して文字列を分割するだけの場合、文字の途中で文字列を分割できます。疑わしいときは、mb_strlen() / mb_substr()はもう少し簡単です。
strposとsubstrを使用します。
<?php
$longString = "I have a code snippet written in PHP that pulls a block of text.";
$truncated = substr($longString,0,strpos($longString,' ',30));
echo $truncated;
これにより、30文字の後の最初のスペースで文字列が切り捨てられます。
どうぞ:
function neat_trim($str, $n, $delim='…') {
$len = strlen($str);
if ($len > $n) {
preg_match('/(.{' . $n . '}.*?)\b/', $str, $matches);
return rtrim($matches[1]) . $delim;
}
else {
return $str;
}
}
$shorttext = preg_replace('/^([\s\S]{1,200})[\s]+?[\s\S]+/', '$1', $fulltext);
説明:
^
-文字列の最初から開始([\s\S]{1,200})
-1〜200の任意のキャラクターを取得する[\s]+?
-短いテキストの最後にスペースを含めないword ...
でください。word...
[\s\S]+
-他のすべてのコンテンツに一致テスト:
regex101.com
or
他のいくつかに追加しましょうr
regex101.com
orrrr
ちょうど200文字です。regex101.com
5番目以降はr
orrrrr
除外されます。楽しい。
$1
はこれが「代替品」であることを知っていますが、この特定のコンテキストでは何を指しているのですか?空の変数?
$1
かっこ内で一致する@Anthony 参照([\s\S]{1,200})
。$2
パターン内にブラケットがある場合、2つの2対のブラケットを参照します。
この問題の完璧な解決策を見つけるのがどれほど難しいかは驚くべきことです。このページで、少なくとも一部の状況で失敗しない回答(特に、文字列に改行またはタブが含まれている場合、または単語の区切りがスペース以外の場合、または文字列にUTF-が含まれている場合)をまだ見つけていません8マルチバイト文字)。
すべてのケースで機能する簡単なソリューションを次に示します。ここでも同様の答えがありましたが、「s」修飾子は複数行の入力を操作する場合に重要であり、「u」修飾子はUTF-8マルチバイト文字を正しく評価します。
function wholeWordTruncate($s, $characterCount)
{
if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
return $s;
}
これで考えられる1つのエッジケース...文字列の最初の$ characterCount文字に空白がない場合、文字列全体が返されます。単語の境界でなくても$ characterCountで強制的に中断したい場合は、次のように使用できます。
function wholeWordTruncate($s, $characterCount)
{
if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
return mb_substr($return, 0, $characterCount);
}
最後のオプションとして、文字列を切り詰める場合は省略記号を追加します...
function wholeWordTruncate($s, $characterCount, $addEllipsis = ' …')
{
$return = $s;
if (preg_match("/^.{1,$characterCount}\b/su", $s, $match))
$return = $match[0];
else
$return = mb_substr($return, 0, $characterCount);
if (strlen($s) > strlen($return)) $return .= $addEllipsis;
return $return;
}
これを行うにはpreg_match関数を使用します。必要なのは非常に単純な式だからです。
$matches = array();
$result = preg_match("/^(.{1,199})[\s]/i", $text, $matches);
この表現は、「スペースで終了する、長さが1から200の範囲の任意の部分文字列に一致する」という意味です。結果は$ resultにあり、一致は$ matchesにあります。これで元の質問が処理されます。これは具体的には任意のスペースで終わります。改行で終了させる場合は、正規表現を次のように変更します。
$result = preg_match("/^(.{1,199})[\n]/i", $text, $matches);
上記の回答に基づいてこれの別のバージョンを取得しましたが、さらに考慮に入れて(utf-8、\ nおよび&nbsp;)、wpで使用した場合にコメント化されたワードプレスショートコードを削除する行も使用します。
function neatest_trim($content, $chars)
if (strlen($content) > $chars)
{
$content = str_replace(' ', ' ', $content);
$content = str_replace("\n", '', $content);
// use with wordpress
//$content = strip_tags(strip_shortcodes(trim($content)));
$content = strip_tags(trim($content));
$content = preg_replace('/\s+?(\S+)?$/', '', mb_substr($content, 0, $chars));
$content = trim($content) . '...';
return $content;
}
/*
Cut the string without breaking any words, UTF-8 aware
* param string $str The text string to split
* param integer $start The start position, defaults to 0
* param integer $words The number of words to extract, defaults to 15
*/
function wordCutString($str, $start = 0, $words = 15 ) {
$arr = preg_split("/[\s]+/", $str, $words+1);
$arr = array_slice($arr, $start, $words);
return join(' ', $arr);
}
使用法:
$input = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.';
echo wordCutString($input, 0, 10);
これは最初の10ワードを出力します。
の preg_split
関数は、部分文字列に文字列を分割するために使用されます。文字列が分割される境界は、正規表現パターンを使用して指定されます。
preg_split
functionは4つのパラメーターを受け取りますが、現時点で関係があるのは最初の3つだけです。
最初のパラメーター–パターン最初のパラメーターは、文字列が分割される正規表現パターンです。この例では、単語の境界を越えて文字列を分割します。したがって、定義済みの文字クラスを使用します\s
、スペース、タブ、キャリッジリターン、ラインフィードなどの空白文字に一致ます。
2番目のパラメーター–入力文字列2番目のパラメーターは、分割する長いテキスト文字列です。
3番目のパラメーター–制限3番目のパラメーターは、返される部分文字列の数を指定します。制限をn
に設定すると、preg_splitはn要素の配列を返します。最初のn-1
要素には部分文字列が含まれます。最後の(n th)
要素には、残りの文字列が含まれます。
私はほとんどあなたが望むことをする関数を持っています、あなたがいくつかの編集をするなら、それはぴったり合うでしょう:
<?php
function stripByWords($string,$length,$delimiter = '<br>') {
$words_array = explode(" ",$string);
$strlen = 0;
$return = '';
foreach($words_array as $word) {
$strlen += mb_strlen($word,'utf8');
$return .= $word." ";
if($strlen >= $length) {
$strlen = 0;
$return .= $delimiter;
}
}
return $return;
}
?>
これは私がそれをした方法です:
$string = "I appreciate your service & idea to provide the branded toys at a fair rent price. This is really a wonderful to watch the kid not just playing with variety of toys but learning faster compare to the other kids who are not using the BooksandBeyond service. We wish you all the best";
print_r(substr($string, 0, strpos(wordwrap($string, 250), "\n")));
substrに似た関数を作成し、@ Daveのアイデアを使用します。
function substr_full_word($str, $start, $end){
$pos_ini = ($start == 0) ? $start : stripos(substr($str, $start, $end), ' ') + $start;
if(strlen($str) > $end){ $pos_end = strrpos(substr($str, 0, ($end + 1)), ' '); } // IF STRING SIZE IS LESSER THAN END
if(empty($pos_end)){ $pos_end = $end; } // FALLBACK
return substr($str, $pos_ini, $pos_end);
}
Ps .:完全な長さのカットはsubstrよりも少ない場合があります。
スペースなしで文字列を処理するために、DaveおよびAmalMuraliからのコードにIF / ELSEIFステートメントを追加
if ((strpos($string, ' ') !== false) && (strlen($string) > 200)) {
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));
}
elseif (strlen($string) > 200) {
$WidgetText = substr($string, 0, 200);
}
私はこれがうまくいくと思います:
function abbreviate_string_to_whole_word($ string、$ max_length、$ buffer){
if (strlen($string)>$max_length) {
$string_cropped=substr($string,0,$max_length-$buffer);
$last_space=strrpos($string_cropped, " ");
if ($last_space>0) {
$string_cropped=substr($string_cropped,0,$last_space);
}
$abbreviated_string=$string_cropped." ...";
}
else {
$abbreviated_string=$string;
}
return $abbreviated_string;
}
バッファを使用すると、返される文字列の長さを調整できます。
これはかなり古い質問ですが、PHP 4.3以降では言及されておらず有効であるため、別の方法を提供すると思いました。
精度修飾子sprintf
を使用することにより、関数ファミリーを使用してテキストを切り捨てる ことができます%.ℕs
。
ピリオドの
.
後に整数が続く意味は、指定子によって異なります。
- e、E、f、およびF指定子の場合:これは、小数点の後に印刷される桁数です(デフォルトでは、これは6です)。
- gおよびG指定子の場合:これは、印刷される有効数字の最大数です。
- s指定子の場合:カットオフポイントとして機能し、文字列の最大文字数制限を設定します
$string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var_dump(sprintf('%.10s', $string));
結果
string(10) "0123456789"
以降のsprintf
機能と同様にsubstr
、部分的に言葉を遮断します。以下のアプローチではstrpos(wordwrap(..., '[break]'), '[break]')
、特別な区切り文字を使用して単語がカットオフされないようにします。これにより、位置を取得し、標準の文構造と一致しないようにすることができます。
必要に応じて改行を保持しながら、部分的に単語を切り取らずに、指定された幅を超えない文字列を返します。
function truncate($string, $width, $on = '[break]') {
if (strlen($string) > $width && false !== ($p = strpos(wordwrap($string, $width, $on), $on))) {
$string = sprintf('%.'. $p . 's', $string);
}
return $string;
}
var_dump(truncate('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 20));
var_dump(truncate("Lorem Ipsum is simply dummy text of the printing and typesetting industry.", 20));
var_dump(truncate("Lorem Ipsum\nis simply dummy text of the printing and typesetting industry.", 20));
結果
/*
string(36) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string(14) "Lorem Ipsum is"
string(14) "Lorem Ipsum
is"
*/
wordwrap($string, $width)
またはを使用した結果strtok(wordwrap($string, $width), "\n")
/*
string(14) "Lorem Ipsum is"
string(11) "Lorem Ipsum"
*/
ここでこれを試すことができます
substr( $str, 0, strpos($str, ' ', 200) );