Bri*_*ian 177 php string function
我有一个用PHP编写的代码片段,它从数据库中提取一个文本块并将其发送到网页上的小部件.原始文本块可以是冗长的文章或短句或短句; 但对于这个小部件,我不能显示超过200个字符.我可以使用substr()来切断200个字符的文本,但结果会在单词中间切断 - 我真正想要的是在200个字符之前在最后一个单词的末尾剪切文本.
Gre*_*her 217
通过使用wordwrap功能.它将文本分成多行,使得最大宽度是您指定的宽度,在字边界处断开.拆分后,您只需占用第一行:
substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));
Run Code Online (Sandbox Code Playgroud)
这个oneliner无法处理的一件事是文本本身短于所需宽度的情况.要处理这种边缘情况,应该做以下事情:
if (strlen($string) > $your_desired_width)
{
$string = wordwrap($string, $your_desired_width);
$string = substr($string, 0, strpos($string, "\n"));
}
Run Code Online (Sandbox Code Playgroud)
如果在实际切割点之前包含换行符,则上述解决方案存在过早切割文本的问题.这是一个解决这个问题的版本:
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));
}
Run Code Online (Sandbox Code Playgroud)
此外,这里是用于测试实现的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));
}
}
Run Code Online (Sandbox Code Playgroud)
不处理像'à'这样的特殊UTF8字符.在REGEX的末尾添加'u'来处理它:
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);
mat*_*mac 136
这将返回单词的前200个字符:
preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));
Run Code Online (Sandbox Code Playgroud)
小智 45
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));
Run Code Online (Sandbox Code Playgroud)
而且你有它 - 一种可靠的方法,可以将任何字符串截断为最接近的整个单词,同时保持在最大字符串长度之下.
我尝试过上面的其他例子,但没有产生预期的结果.
Ser*_*nko 36
当我注意到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");
}
Run Code Online (Sandbox Code Playgroud)
示例#1.
print truncate("This is very long string with many chars.", 25);
Run Code Online (Sandbox Code Playgroud)
上面的例子将输出:
This is very long string...
Run Code Online (Sandbox Code Playgroud)
例#2.
print truncate("This is short string.", 25);
Run Code Online (Sandbox Code Playgroud)
上面的例子将输出:
This is short string.
Run Code Online (Sandbox Code Playgroud)
每当你在某些语言(例如中文和日文)不使用空格字符来分割单词时,请记住"单词".此外,恶意用户可以简单地输入没有任何空格的文本,或使用与标准空格字符类似的Unicode,在这种情况下,您使用的任何解决方案最终都可能最终显示整个文本.解决这个问题的方法可能是在正常分割空格后检查字符串长度,然后,如果字符串仍然高于异常限制 - 在这种情况下可能是225个字符 - 继续并在该限制下愚蠢地将其拆分.
对于非ASCII字符,还有一个需要注意的事情; 包含它们的字符串可能被PHP的标准strlen()解释为比它们实际上更长,因为单个字符可能需要两个或更多字节而不是一个字节.如果你只是使用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;
Run Code Online (Sandbox Code Playgroud)
这将为您提供在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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的功能基于@ Cd-MaN的方法.
function shorten($string, $width) {
if(strlen($string) > $width) {
$string = wordwrap($string, $width);
$string = substr($string, 0, strpos($string, "\n"));
}
return $string;
}
Run Code Online (Sandbox Code Playgroud)
$shorttext = preg_replace('/^([\s\S]{1,200})[\s]+?[\s\S]+/', '$1', $fulltext);
Run Code Online (Sandbox Code Playgroud)
描述:
^ - 从字符串的开头开始([\s\S]{1,200}) - 获得 1 到 200 个任意字符[\s]+?- 在短文本末尾不包含空格,因此我们可以避免word ...代替word...[\s\S]+ - 匹配所有其他内容测试:
regex101.com让我们添加or其他一些rregex101.com orrrr 正好 200 个字符。regex101.com经过第五次r orrrrr排除。享受。