데이터베이스에서 텍스트 블록을 가져 와서 웹 페이지의 위젯으로 보내는 PHP로 작성된 코드 스 니펫이 있습니다. 원본 텍스트 블록은 긴 기사 나 짧은 문장 또는 두 문장 일 수 있습니다. 그러나이 위젯의 경우 200 자 이상을 표시 할 수 없습니다. substr ()을 사용하여 200 자로 텍스트를자를 수 있지만 결과는 단어 중간에서 잘릴 수 있습니다. 실제로 원하는 것은 200 자 전에 마지막 단어 의 끝에서 텍스트를 자르는 것 입니다.
데이터베이스에서 텍스트 블록을 가져 와서 웹 페이지의 위젯으로 보내는 PHP로 작성된 코드 스 니펫이 있습니다. 원본 텍스트 블록은 긴 기사 나 짧은 문장 또는 두 문장 일 수 있습니다. 그러나이 위젯의 경우 200 자 이상을 표시 할 수 없습니다. substr ()을 사용하여 200 자로 텍스트를자를 수 있지만 결과는 단어 중간에서 잘릴 수 있습니다. 실제로 원하는 것은 200 자 전에 마지막 단어 의 끝에서 텍스트를 자르는 것 입니다.
답변:
워드 랩 기능 을 사용합니다 . 텍스트를 여러 줄로 분할하여 최대 너비가 지정한 너비로 단어 경계를 어기도록합니다. 분할 후 간단히 첫 번째 줄을 가져옵니다.
substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));
이 oneliner가 처리하지 않는 한 가지는 텍스트 자체가 원하는 너비보다 짧은 경우입니다. 이 경우를 처리하려면 다음과 같은 작업을 수행해야합니다.
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 테스트 클래스는 다음과 같습니다.
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
원하는 너비보다 앞에 텍스트가 있으면 텍스트를 조기에 자르는 것처럼 보입니다 .
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 $ 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)
모든 공백 문자를 단일 공백으로 대체하기 위해 항상 사전 처리 할 수 있습니다 .)
중국어 및 일본어와 같은 일부 언어는 공백 문자를 사용하여 단어를 나누지 않는 "단어"로 분할 할 때마다 유의하십시오. 또한 악의적 인 사용자는 공백없이 텍스트를 입력하거나 표준 공백 문자와 비슷한 유니 코드를 사용하여 텍스트를 입력 할 수 있습니다.이 경우 사용하는 솔루션이 전체 텍스트를 표시 할 수 있습니다. 이 문제를 해결하는 방법은 문자열을 공백으로 분할 한 후 문자열 길이를 확인한 다음 문자열이 여전히 비정상적인 제한 (이 경우 225 자) 이상인 경우 계속 진행하여 그 한계에서 바보로 분할하는 것입니다.
비 ASCII 문자와 관련하여 이와 같은 사항에 한 가지 더주의해야합니다. PHP의 표준 strlen ()에 의해 포함 된 문자열은 실제보다 더 긴 것으로 해석 될 수 있습니다. 단일 문자는 하나가 아닌 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
다섯 번째 r
orrrrr
제외 후 .즐겨.
$1
"대체" 라는 것을 알고 있지만,이 특정 맥락에서 그것이 무엇을 의미 합니까 ? 빈 변수?
$1
대괄호 안에 일치하도록 참조합니다 ([\s\S]{1,200})
. $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;
}
이 경우 한 가지 가능한 경우 ... 문자열에 첫 $ 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);
위의 답변을 기반으로 다른 버전을 얻었지만 wp와 함께 사용하면 주석이 달린 짧은 코드를 제거하는 줄 (utf-8, \ n 및 & nbsp;)을 더 고려합니다.
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
함수는 4 개의 매개 변수를 취하지 만 현재 처음 3 개만 관련이 있습니다.
첫 번째 매개 변수 – 패턴 첫 번째 매개 변수는 문자열을 분할 할 정규식 패턴입니다. 이 경우 문자열을 단어 경계에 걸쳐 분할하려고합니다. 따라서 사전 정의 된 문자 클래스를 사용합니다\s
공백, 탭, 캐리지 리턴 및 줄 바꿈과 같은 공백 문자와 일치 를 .
두 번째 매개 변수 – 입력 문자열 두 번째 매개 변수는 분할하려는 긴 텍스트 문자열입니다.
세 번째 매개 변수 – 제한 세 번째 매개 변수는 반환해야하는 하위 문자열 수를 지정합니다. 한계를로 설정하면 n
preg_split은 n 개의 요소 배열을 반환합니다. 첫 번째 n-1
요소에는 하위 문자열이 포함됩니다. 마지막 (n th)
요소는 나머지 문자열을 포함합니다.
@Justin Poliey의 정규식을 기반으로합니다.
// Trim very long text to 120 characters. Add an ellipsis if the text is trimmed.
if(strlen($very_long_text) > 120) {
$matches = array();
preg_match("/^(.{1,120})[\s]/i", $very_long_text, $matches);
$trimmed_text = $matches[0]. '...';
}
나는 당신이 원하는 것을 거의하는 기능을 가지고 있습니다. 몇 가지 편집을하면 정확하게 맞습니다.
<?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);
}
추신 : 전체 길이 컷은 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);
}
나는 이것이 효과가 있음을 발견했다.
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;
}
버퍼를 사용하면 반환 된 문자열의 길이를 조정할 수 있습니다.
이것을 사용하십시오 :
다음 코드는 ','를 제거합니다. 다른 문자 또는 하위 문자열이 있으면 ','대신 사용할 수 있습니다.
substr($string, 0, strrpos(substr($string, 0, $comparingLength), ','))
// 다른 문자열 계정이있는 경우
substr($string, 0, strrpos(substr($string, 0, $comparingLength-strlen($currentString)), ','))
이것은 다소 오래된 질문이지만 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) );