วิธีตัดทอนสตริงใน PHP เป็นคำที่ใกล้เคียงกับจำนวนอักขระมากที่สุด?


183

ฉันมีข้อมูลโค้ดเขียนใน PHP ที่ดึงบล็อกข้อความจากฐานข้อมูลและส่งออกไปยังวิดเจ็ตบนหน้าเว็บ กลุ่มข้อความต้นฉบับอาจเป็นบทความที่มีความยาวหรือประโยคสั้น ๆ หรือสองประโยคก็ได้ แต่สำหรับวิดเจ็ตนี้ฉันไม่สามารถแสดงได้มากกว่าพูด 200 ตัวอักษร ฉันสามารถใช้ substr () เพื่อตัดข้อความที่ 200 chars แต่ผลลัพธ์จะถูกตัดออกกลางคำ - สิ่งที่ฉันต้องการคือการสับข้อความที่ท้ายคำสุดท้ายก่อน 200 chars


2
คำถามตั้งใจจะบอกว่าข้อความที่ถูกตัดทอนจะพอดีกับจำนวนพิกเซลคงที่ในหน้าเว็บ ในกรณีนี้ขึ้นอยู่กับฟอนต์ที่เลือกพื้นที่ที่ต้องการต่ออักขระไม่คงที่ และด้วยเหตุนี้เราจึงไม่สามารถคาดเดาได้ว่า 200 ตัวอักษรจะพอดีที่สุดในจำนวนพิกเซลที่มีอยู่ จนถึงตอนนี้ (จนถึง 02- มี.ค. -54) คำตอบทั้งหมดด้านล่างจะหายไปในจุดนี้จึงไม่มีคำตอบใดที่เชื่อถือได้ - :(
LionHeart

1
ไม่ไม่จริง คุณสามารถตั้งค่าฟอนต์ในรูปแบบที่เชื่อถือได้และวัดสถานการณ์กรณีที่เลวร้ายที่สุดหรือจำนวนอักขระที่กว้างที่สุดที่จะพอดีและถ้าคุณต้องแน่ใจว่า 100% ว่าเบราว์เซอร์แสดงผลอย่างไรมันไม่ใช่ปัญหา PHP อีกต่อไป
Mołot

ลองใช้ลิงค์นี้อาจช่วยให้คุณ stackoverflow.com/a/26098951/3944217
edCoder

คุณอาจพบว่ามีs($str)->truncateSafely(200)ประโยชน์ดังที่พบในไลบรารีแบบสแตนด์อโลนนี้
caw

คำตอบ:


221

โดยใช้ฟังก์ชั่นwordwrap มันแยกข้อความในหลายบรรทัดเช่นที่ความกว้างสูงสุดคือคนที่คุณระบุแบ่งที่ขอบเขตของคำ หลังจากแยกคุณเพียงใช้บรรทัดแรก:

substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));

สิ่งหนึ่งที่ผู้ประกอบการรายนี้ไม่จัดการคือกรณีที่ตัวอักษรสั้นกว่าความกว้างที่ต้องการ ในการจัดการกับเคสแบบขอบนี้คุณควรทำสิ่งต่อไปนี้:

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 พิเศษเช่น 'à' เพิ่ม 'u' ในตอนท้ายของ REGEX เพื่อจัดการ:

$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);


1
ดูเหมือนว่ามันจะตัดข้อความก่อนกำหนดหากมี\nความกว้างที่ต้องการก่อนหน้า
เคนดัลล์ฮอปกินส์

@KendallHopkins: จริงมีปัญหา ฉันอัปเดตคำตอบด้วยการใช้งานทางเลือกซึ่งแก้ไขปัญหาที่ระบุ
Panther สีเทา

ตัวอย่างนี้จะทำงานกับสตริงที่มีแท็ก html เหมือนแท็กวรรคหรือไม่
limitlessloop

มันเป็นประโยชน์กับฉันจริงๆปวดหัวของฉันเป็นArabicตัวอักษรยาวและลดคำที่ถูกต้องลงไปตอนนี้ด้วยความช่วยเหลือของtokenTruncateฟังก์ชั่น .. tnx a million :)
Aditya P Bhatt

1
ทำไมไม่เพิ่ม: ถ้า (strlen ($ string) <= $ your_desired_width) ส่งกลับ $ string; เป็นคำสั่งแรก?
Darko Romanov

139

สิ่งนี้จะส่งกลับคำ 200 อักขระแรกของคำ:

preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));

7
เกือบจะ ดูเหมือนว่าจะลบคำสุดท้ายของประโยคสำหรับฉันไม่ว่าจะเกิดอะไรขึ้น
ReX357

ใช้งานได้ดี แต่ฉันพบข้อผิดพลาดเดียวกับ ReX357 เมื่อมีมากกว่า 1 คำมันจะลบคำสุดท้าย
Andres SK

25
เพียงห่อไว้ในเช็คเพื่อให้แน่ใจว่าสายอักขระยาวกว่าที่คุณกำลังทดสอบ (เช่นเดียวกับคำตอบที่ยอมรับ)if (strlen($string) > $your_desired_width) { preg_replace(...); }
Blair McMillan

ฉันแก้ไขคำตอบเพื่อรวม @BlairMcMillan แนะนำ
Kim Stacks

2
การปรับปรุงเล็ก ๆ ของ regex: วงเล็บทำให้ \ \ S สุดท้ายเป็นตัวเลือกในการแข่งขัน แต่พวกเขายังจับตัวละครเหล่านั้น เนื่องจากเราไม่ได้ต้องการที่จะจับตัวอักษรเหล่านั้นให้วงเล็บไม่ใช่การจับชอบโดย:/\s+?(?:\S+)?$/
pcronin

45
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));

และคุณก็มี - วิธีที่เชื่อถือได้ของการตัดสตริงใด ๆ ให้เป็นคำที่ใกล้ที่สุดขณะที่อยู่ภายใต้ความยาวสตริงสูงสุด

ฉันลองตัวอย่างอื่น ๆ ด้านบนและพวกเขาไม่ได้ผลลัพธ์ตามที่ต้องการ


11
หากความยาวของสตริงที่ระบุมีค่าน้อยกว่าความยาวสูงสุดสิ่งนี้จะตัดทุกอย่างออกจนกว่าจะถึงช่องว่างสุดท้าย เพื่อหลีกเลี่ยงปัญหานี้ให้ห่อสิ่งเหล่านี้ไว้ในifคำแถลง:if (strlen($str) > 200) { ... }
Amal Murali

ง่ายและอาจเร็วกว่าโซลูชันอื่น ๆ
วลาด

1
ปัญหาหนึ่งที่เกิดขึ้นกับสิ่งนี้คือมันส่งคืนสตริงว่างถ้าสตริงไม่มีช่องว่าง
orrd

สามารถย่อให้เป็น:$WidgetText = substr($string, 0, strpos($string, ' ', 200));
wranvaud

36

วิธีแก้ปัญหาต่อไปนี้เกิดขึ้นเมื่อฉันสังเกตเห็นพารามิเตอร์ $ break ของฟังก์ชันwordwrap :

สตริง wordwrap (สตริง $ str [, int $ width = 75 [, สตริง $ 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.

2
นี้ไม่ทำงานถ้าสตริงที่มีอยู่แล้วมีเส้นตัวละครใหม่ (เช่นถ้าคุณกำลังพยายามที่จะแยกdescriptionของบล็อกโพสต์)
supersan

1
@supersan สามารถประมวลผลล่วงหน้าด้วยเสมอpreg_replace('/\s+/', ' ', $description)เพื่อแทนที่อักขระช่องว่างทั้งหมดด้วยช่องว่างเดียว;)
Mavelo

9

โปรดจำไว้ว่าเมื่อใดก็ตามที่คุณแยกโดย "คำว่า" ทุกที่ที่บางภาษาเช่นจีนและญี่ปุ่นไม่ได้ใช้อักขระช่องว่างเพื่อแยกคำ นอกจากนี้ผู้ใช้ที่เป็นอันตรายสามารถป้อนข้อความโดยไม่มีช่องว่างหรือใช้ Unicode ที่มีลักษณะเหมือนอักขระช่องว่างมาตรฐานซึ่งในกรณีนี้โซลูชันใด ๆ ที่คุณใช้อาจปรากฏข้อความทั้งหมดขึ้นมา วิธีนี้อาจเป็นการตรวจสอบความยาวของสายอักขระหลังจากแยกในช่องว่างตามปกติจากนั้นถ้าสตริงยังคงเกินขีด จำกัด ที่ผิดปกติ - อาจมีอักขระ 225 ตัวในกรณีนี้ - ดำเนินการต่อไป

ข้อแม้อีกหนึ่งอย่างเกี่ยวกับสิ่งนี้เมื่อพูดถึงตัวละครที่ไม่ใช่ ASCII; สตริงที่มีพวกเขาอาจถูกตีความโดย strlen มาตรฐานของ PHP () ว่านานกว่าที่พวกเขาเป็นจริงเพราะอักขระตัวเดียวอาจใช้เวลาอย่างน้อยสองไบต์มากกว่าหนึ่ง หากคุณเพียงแค่ใช้ฟังก์ชั่น strlen () / substr () เพื่อแยกสตริงคุณอาจแบ่งสตริงไว้กลางอักขระ! เมื่อมีข้อสงสัยmb_strlen () / mb_substr ()จะเข้าใจผิดได้อีกเล็กน้อย


8

ใช้ 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 ตัว


1
สวัสดีถ้าความยาวสตริงที่ไม่มีช่องว่างจะน้อยกว่า 30 ก็จะส่งคืนข้อผิดพลาด และผลลัพธ์ที่นี่จะเป็นอักขระ 31 ตัวแรกไม่ใช่ 30 ..
Er Anurag Jain

5

ไปเลย:

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;
   }
}

ขอบคุณฉันพบว่าฟังก์ชันที่มีประโยชน์และเชื่อถือได้มากที่สุดของคำตอบเหล่านี้สำหรับความต้องการของฉัน อย่างไรก็ตามฉันจะทำให้มันรองรับสตริงแบบหลายไบต์ได้อย่างไร
ctrlbrk

5

นี่คือฟังก์ชั่นของฉันตามแนวทางของ @ Cd-MaN

function shorten($string, $width) {
  if(strlen($string) > $width) {
    $string = wordwrap($string, $width);
    $string = substr($string, 0, strpos($string, "\n"));
  }

  return $string;
}

4
$shorttext = preg_replace('/^([\s\S]{1,200})[\s]+?[\s\S]+/', '$1', $fulltext);

รายละเอียด:

  • ^ - เริ่มจากจุดเริ่มต้นของสตริง
  • ([\s\S]{1,200}) - รับจาก 1 ถึง 200 ของตัวละครใด ๆ
  • [\s]+?- ไม่รวมช่องว่างในตอนท้ายของข้อความสั้น ๆ เพื่อให้เราสามารถหลีกเลี่ยงการword ...แทนword...
  • [\s\S]+ - จับคู่เนื้อหาอื่น ๆ ทั้งหมด

แบบทดสอบ:

  1. regex101.comลองเพิ่มไปที่orอื่นr
  2. regex101.com orrrr ตรง 200 ตัวอักษร
  3. regex101.comหลังจากห้าr orrrrrไม่รวม

สนุก.


ฉันไม่เข้าใจเอกสาร PHP ฉันรู้ว่า$1มันคือ "การแทนที่" แต่ในบริบทเฉพาะนี้มันหมายถึงอะไร? ตัวแปรว่างเปล่า
oldboy

1
@Anthony อ้างอิงเพื่อให้ตรงกับในวงเล็บ$1 จะอ้างถึงวงเล็บสองคู่ที่สองหากมีรูปแบบใด ๆ ([\s\S]{1,200})$2
hlcs

3

มันน่าแปลกใจที่มันยุ่งยากแค่ไหนในการหาทางออกที่สมบูรณ์แบบสำหรับปัญหานี้ ฉันยังไม่พบคำตอบในหน้านี้ที่ไม่ได้ล้มเหลวอย่างน้อยในบางสถานการณ์ (โดยเฉพาะอย่างยิ่งถ้าสตริงมีการขึ้นบรรทัดใหม่หรือแท็บหรือถ้าตัวแบ่งคำเป็นสิ่งอื่นที่ไม่ใช่ช่องว่างหรือถ้าสตริงมี 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;
}

2

ฉันจะใช้ฟังก์ชัน preg_match เพื่อทำสิ่งนี้ตามที่คุณต้องการคือการแสดงออกที่ค่อนข้างง่าย

$matches = array();
$result = preg_match("/^(.{1,199})[\s]/i", $text, $matches);

นิพจน์หมายถึง "จับคู่สตริงย่อยใด ๆ ที่เริ่มต้นจากจุดเริ่มต้นของความยาว 1-200 ที่ลงท้ายด้วยช่องว่าง" ผลลัพธ์จะเป็นผลลัพธ์ $ และการจับคู่อยู่ในการแข่งขัน $ ที่จะดูแลคำถามเดิมของคุณซึ่งจะสิ้นสุดในพื้นที่ใด ๆ โดยเฉพาะ หากคุณต้องการให้มันขึ้นบรรทัดใหม่ให้เปลี่ยนนิพจน์ปกติเป็น:

$result = preg_match("/^(.{1,199})[\n]/i", $text, $matches);

2

ตกลงดังนั้นฉันได้รับรุ่นอื่นตามคำตอบข้างต้น แต่รับสิ่งเพิ่มเติมในบัญชี (utf-8, \ n และ & nbsp;) นอกจากนี้ยังมีบรรทัดที่ตัดรหัสย่อที่แสดงความคิดเห็นถ้าใช้กับ WP

function neatest_trim($content, $chars) 
  if (strlen($content) > $chars) 
  {
    $content = str_replace('&nbsp;', ' ', $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;
  }

2

นี่เป็นการแก้ไขเล็กน้อยสำหรับคำตอบของ mattmac:

preg_replace('/\s+?(\S+)?$/', '', substr($string . ' ', 0, 201));

ข้อแตกต่างเพียงอย่างเดียวคือการเพิ่มช่องว่างท้าย $ string สิ่งนี้ทำให้มั่นใจได้ว่าคำสุดท้ายจะไม่ถูกตัดออกตามความคิดเห็นของ ReX357

ฉันมีคะแนนตัวแทนไม่เพียงพอที่จะเพิ่มสิ่งนี้เป็นความคิดเห็น


2
/*
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 ตัวแรกเท่านั้นที่เกี่ยวข้องกับเราในตอนนี้

First Parameter - Pattern พารามิเตอร์แรกคือรูปแบบนิพจน์ทั่วไปที่สตริงจะถูกแบ่ง ในกรณีของเราเราต้องการแยกสตริงข้ามขอบเขตคำ ดังนั้นเราจึงใช้คลาสอักขระที่กำหนดไว้ล่วงหน้า\sซึ่งตรงกับอักขระช่องว่างสีขาวเช่นช่องว่างแท็บการขึ้นบรรทัดใหม่และการป้อนบรรทัด

พารามิเตอร์ที่สอง - อินพุตสตริงพารามิเตอร์ที่สองคือสตริงข้อความแบบยาวที่เราต้องการแยก

พารามิเตอร์ที่สาม - จำกัด พารามิเตอร์ที่สามระบุจำนวนของสตริงย่อยที่ควรส่งคืน หากคุณตั้งค่าขีด จำกัด เป็นnpreg_split จะส่งคืนอาร์เรย์ขององค์ประกอบ n n-1องค์ประกอบแรกจะมีสารตั้งต้น (n th)องค์ประกอบสุดท้ายจะมีส่วนที่เหลือของสตริง



1

ฉันมีฟังก์ชั่นที่ทำเกือบสิ่งที่คุณต้องการถ้าคุณทำแก้ไขสองสามอย่างมันจะพอดี:

<?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;
}
?>

1

นี่คือวิธีที่ฉันทำ:

$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")));

0

ฉันรู้ว่ามันเก่า แต่ ...

function _truncate($str, $limit) {
    if(strlen($str) < $limit)
        return $str;
    $uid = uniqid();
    return array_shift(explode($uid, wordwrap($str, $limit, $uid)));
}

0

ฉันสร้างฟังก์ชั่นที่คล้ายกับ 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);
}

ปล.: การตัดแบบเต็มความยาวอาจน้อยกว่าพื้นผิว


0

เพิ่มคำสั่ง IF / ELSEIF ให้กับรหัสจากDaveและAmalMuraliสำหรับการจัดการสตริงโดยไม่มีช่องว่าง

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);
}

0

ฉันพบว่างานนี้:

ฟังก์ชัน 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."&nbsp;...";
}
else {
    $abbreviated_string=$string;
}

return $abbreviated_string;

}

บัฟเฟอร์ช่วยให้คุณสามารถปรับความยาวของสตริงที่ส่งคืน


0

ใช้สิ่งนี้:

รหัสต่อไปนี้จะลบ ',' หากคุณมีตัวละครหรือสตริงย่อยใด ๆ คุณสามารถใช้สิ่งนั้นแทน ','

substr($string, 0, strrpos(substr($string, 0, $comparingLength), ','))

// หากคุณมีบัญชีสตริงสำหรับ

substr($string, 0, strrpos(substr($string, 0, $comparingLength-strlen($currentString)), ','))

0

ในขณะนี้เป็นคำถามที่ค่อนข้างเก่าฉันคิดว่าฉันจะให้ทางเลือกเนื่องจากมันไม่ได้กล่าวถึงและใช้ได้สำหรับ PHP 4.3+

คุณสามารถใช้sprintfตระกูลฟังก์ชันเพื่อตัดทอนข้อความโดยใช้ %.ℕsตัวแก้ไขความแม่นยำ

ช่วงเวลา.ตามด้วยเลขจำนวนเต็มที่มีความหมายขึ้นอยู่กับตัวระบุ:

  • สำหรับตัวระบุ e, E, f และ F: นี่คือจำนวนหลักที่จะพิมพ์หลังจุดทศนิยม (โดยค่าเริ่มต้นนี่คือ 6)
  • สำหรับตัวระบุ g และ G: นี่คือจำนวนหลักที่สำคัญที่จะพิมพ์
  • สำหรับตัวระบุ: มันทำหน้าที่เป็นจุดตัดการตั้งค่าการ จำกัด อักขระสูงสุดให้กับสตริง

การตัดปลายอย่างง่ายhttps://3v4l.org/QJDJU

$string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var_dump(sprintf('%.10s', $string));

ผลลัพธ์

string(10) "0123456789"

Truncation แบบขยายhttps://3v4l.org/FCD21

เนื่องจาก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"
*/

-1

ฉันเคยใช้มันมาก่อน

<?php
    $your_desired_width = 200;
    $string = $var->content;
    if (strlen($string) > $your_desired_width) {
        $string = wordwrap($string, $your_desired_width);
        $string = substr($string, 0, strpos($string, "\n")) . " More...";
    }
    echo $string;
?>

-1

ที่นี่คุณสามารถลองสิ่งนี้

substr( $str, 0, strpos($str, ' ', 200) ); 

คำตอบนั้นได้ถูกกล่าวถึงแล้วในคำตอบอื่น ๆ ปัญหาของมันคือมันล้มเหลวถ้าสตริงน้อยกว่า 200 ตัวอักษรหรือถ้ามันไม่มีช่องว่างใด ๆ มันไม่ได้ จำกัด สตริงไว้ที่ 200 ตัวอักษร แต่มันจะแบ่งสตริงที่ช่องว่างหลังจาก 200 ตัวอักษรซึ่งโดยปกติจะไม่ใช่สิ่งที่คุณต้องการ
orrd

-1

ฉันเชื่อว่านี่เป็นวิธีที่ง่ายที่สุดที่จะทำ:

$lines = explode('♦♣♠',wordwrap($string, $length, '♦♣♠'));
$newstring = $lines[0] . ' &bull; &bull; &bull;';

ฉันใช้ตัวละครพิเศษเพื่อแยกข้อความและตัดมัน


-2

อาจจะเป็นสิ่งนี้จะช่วยให้ใครบางคน:

<?php

    $string = "Your line of text";
    $spl = preg_match("/([, \.\d\-''\"\"_()]*\w+[, \.\d\-''\"\"_()]*){50}/", $string, $matches);
    if (isset($matches[0])) {
        $matches[0] .= "...";
        echo "<br />" . $matches[0];
    } else {
        echo "<br />" . $string;
    }

?>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.