为了获取 UTF-8 字符的子字符串,我强烈推荐 mb_substr
<?php
$utf8string = "cakeæøå";
echo substr($utf8string,0,5);
// output cake#
echo mb_substr($utf8string,0,5,'UTF-8');
//output cakeæ
?>
(PHP 4、PHP 5、PHP 7、PHP 8)
substr — 返回字符串的一部分
返回由 offset
和 length
参数指定的 string
的部分。
string
输入字符串。
offset
如果 offset
为非负数,则返回的字符串将从 string
中的第 offset
个位置开始,从零开始计数。例如,在字符串 'abcdef
' 中,位置 0
处的字符是 'a
',位置 2
处的字符是 'c
',依此类推。
如果 offset
为负数,则返回的字符串将从 string
末尾的第 offset
个字符开始。
如果 string
的长度小于 offset
个字符,则返回空字符串。
示例 #1 使用负数 offset
<?php
$rest = substr("abcdef", -1); // 返回 "f"
$rest = substr("abcdef", -2); // 返回 "ef"
$rest = substr("abcdef", -3, 1); // 返回 "d"
?>
length
如果指定了 length
且为正数,则返回的字符串将包含从 offset
开始的最多的 length
个字符(取决于 string
的长度)。
如果指定了 length
且为负数,则将在 string
末尾省略这么多字符(在计算 offset
为负数时的起始位置后)。如果 offset
表示此截断位置或之后的位置,则将返回空字符串。
如果指定了 length
且为 0
,则将返回空字符串。
如果省略 length
或为 null
,则将返回从 offset
开始到字符串末尾的子字符串。
示例 #2 使用负数 length
<?php
$rest = substr("abcdef", 0, -1); // 返回 "abcde"
$rest = substr("abcdef", 2, -1); // 返回 "cde"
$rest = substr("abcdef", 4, -4); // 返回 ""; 在 PHP 8.0.0 之前,返回 false
$rest = substr("abcdef", -3, -1); // 返回 "de"
?>
返回 string
的提取部分,或空字符串。
版本 | 描述 |
---|---|
8.0.0 |
length 现在可以为空。当 length 显式设置为 null 时,该函数返回在字符串末尾结束的子字符串,而以前它返回空字符串。 |
8.0.0 | 该函数返回空字符串,而以前它返回 false 。 |
示例 #3 基本 substr() 用法
<?php
echo substr('abcdef', 1); // bcdef
echo substr("abcdef", 1, null); // bcdef; 在 PHP 8.0.0 之前,返回空字符串
echo substr('abcdef', 1, 3); // bcd
echo substr('abcdef', 0, 4); // abcd
echo substr('abcdef', 0, 8); // abcdef
echo substr('abcdef', -1, 1); // f
// 访问字符串中的单个字符
// 也可以使用 "方括号"
$string = 'abcdef';
echo $string[0]; // a
echo $string[3]; // d
echo $string[strlen($string)-1]; // f
?>
示例 #4 substr() 转换行为
<?php
class apple {
public function __toString() {
return "green";
}
}
echo "1) ".var_export(substr("pear", 0, 2), true).PHP_EOL;
echo "2) ".var_export(substr(54321, 0, 2), true).PHP_EOL;
echo "3) ".var_export(substr(new apple(), 0, 2), true).PHP_EOL;
echo "4) ".var_export(substr(true, 0, 1), true).PHP_EOL;
echo "5) ".var_export(substr(false, 0, 1), true).PHP_EOL;
echo "6) ".var_export(substr("", 0, 1), true).PHP_EOL;
echo "7) ".var_export(substr(1.2e3, 0, 4), true).PHP_EOL;
?>
上面的示例将输出
1) 'pe' 2) '54' 3) 'gr' 4) '1' 5) '' 6) '' 7) '1200'
示例 #5 无效字符范围
如果请求无效的字符范围,substr() 从 PHP 8.0.0 开始返回空字符串;之前,false
则返回。
<?php
var_dump(substr('a', 2));
?>
以上示例在 PHP 8 中的输出
string(0) ""
以上示例在 PHP 7 中的输出
bool(false)
为了获取 UTF-8 字符的子字符串,我强烈推荐 mb_substr
<?php
$utf8string = "cakeæøå";
echo substr($utf8string,0,5);
// output cake#
echo mb_substr($utf8string,0,5,'UTF-8');
//output cakeæ
?>
也许通过以下函数更容易从字符串中提取需要的子部分
<?php
after ('@', '[email protected]');
//returns 'online.ge'
//from the first occurrence of '@'
before ('@', '[email protected]');
//returns 'biohazard'
//from the first occurrence of '@'
between ('@', '.', '[email protected]');
//returns 'online'
//from the first occurrence of '@'
after_last ('[', 'sin[90]*cos[180]');
//returns '180]'
//from the last occurrence of '['
before_last ('[', 'sin[90]*cos[180]');
//returns 'sin[90]*cos['
//from the last occurrence of '['
between_last ('[', ']', 'sin[90]*cos[180]');
//returns '180'
//from the last occurrence of '['
?>
以下是代码
<?php
function after ($this, $inthat)
{
if (!is_bool(strpos($inthat, $this)))
return substr($inthat, strpos($inthat,$this)+strlen($this));
};
function after_last ($this, $inthat)
{
if (!is_bool(strrevpos($inthat, $this)))
return substr($inthat, strrevpos($inthat, $this)+strlen($this));
};
function before ($this, $inthat)
{
return substr($inthat, 0, strpos($inthat, $this));
};
function before_last ($this, $inthat)
{
return substr($inthat, 0, strrevpos($inthat, $this));
};
function between ($this, $that, $inthat)
{
return before ($that, after($this, $inthat));
};
function between_last ($this, $that, $inthat)
{
return after_last($this, before_last($that, $inthat));
};
// use strrevpos function in case your php version does not include it
function strrevpos($instr, $needle)
{
$rev_pos = strpos (strrev($instr), strrev($needle));
if ($rev_pos===false) return false;
else return strlen($instr) - $rev_pos - strlen($needle);
};
?>
从经典的 ASP 转到 PHP 后,我习惯了 ASP 中内置的 Left() 和 Right() 函数,所以我快速地做了一个 PHP 版本。希望这些能帮助其他正在进行切换的人。
function left($str, $length) {
return substr($str, 0, $length);
}
function right($str, $length) {
return substr($str, -$length);
}
<?Php
### 使用 substr() 和 strpos() 按单词截取字符串 #####
### 此脚本将返回不包含单词中断的字符串部分 ###
$description = ‘your description here your description here your description here your description here your description here your description here your description hereyour description here your description here’ // 您的描述在此处 .
$no_letter = 30 ;
if(strlen($desctiption) > 30 )
{
echo substr($description,0,strpos($description,’ ‘,30)); // strpos 用于查找 30 个字符后的 ‘ ‘。
}
else {
echo $description;
}
?>
这将返回由开始和长度参数指定的 str 的部分。
它可以在字符数上执行多字节安全操作,类似于 mb_strcut() ...
注意
1. 像这样使用 bite_str(string str, int start, int length [,byte of on string]);
2. 第一个字符的位置是 0。第二个字符的位置是 1,依此类推...
3. $byte 是您编码的一个字符长度,例如:utf-8 是 "3",gb2312 和 big5 是 "2"...您可以使用函数 strlen() 获取它...
享受它 :) ...
--- Bleakwind
QQ:940641
http://www.weaverdream.com
PS: 对不起,我的英语水平太差了... :(
<?php
// 由 Bleakwind 实现的字符串截取
// utf-8:$byte=3 | gb2312:$byte=2 | big5:$byte=2
function bite_str($string, $start, $len, $byte=3)
{
$str = "";
$count = 0;
$str_len = strlen($string);
for ($i=0; $i<$str_len; $i++) {
if (($count+1-$start)>$len) {
$str .= "...";
break;
} elseif ((ord(substr($string,$i,1)) <= 128) && ($count < $start)) {
$count++;
} elseif ((ord(substr($string,$i,1)) > 128) && ($count < $start)) {
$count = $count+2;
$i = $i+$byte-1;
} elseif ((ord(substr($string,$i,1)) <= 128) && ($count >= $start)) {
$str .= substr($string,$i,1);
$count++;
} elseif ((ord(substr($string,$i,1)) > 128) && ($count >= $start)) {
$str .= substr($string,$i,$byte);
$count = $count+2;
$i = $i+$byte-1;
}
}
return $str;
}
// 测试
$str = "123456???ֽ?123456?ַ???123456??ȡ????";
for($i=0;$i<30;$i++){
echo "<br>".bite_str($str,$i,20);
}
?>
我想找出从字符串中获取前几个字符的最快方法,所以我进行以下实验比较 substr、直接字符串访问和 strstr
<?php
/* substr 访问 */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
$opening = substr($string,0,11);
if ($opening == 'Lorem ipsum'){
true;
}else{
false;
}
}
$endtime1 = endTimer();
/* 直接访问 */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
if ($string[0] == 'L' && $string[1] == 'o' && $string[2] == 'r' && $string[3] == 'e' && $string[4] == 'm' && $string[5] == ' ' && $string[6] == 'i' && $string[7] == 'p' && $string[8] == 's' && $string[9] == 'u' && $string[10] == 'm'){
true;
}else{
false;
}
}
$endtime2 = endTimer();
/* strstr 访问 */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
$opening = strstr($string,'Lorem ipsum');
if ($opening == true){
true;
}else{
false;
}
}
$endtime3 = endTimer();
echo $endtime1."\r\n".$endtime2."\r\n".$endtime3;
?>
该字符串是 6 段 Lorem Ipsum,我尝试匹配前两个单词。实验进行了 3 次并取平均值。结果是
(substr) 3.24
(直接访问) 11.49
(strstr) 4.96
(标准偏差分别为 0.01、0.02 和 0.04)
因此,substr 是三种获取字符串前几个字母的方法中最快的。
[英语]
我用 python 创建了类似于使用 php substr & strrev 函数访问列表或字符串的方法。
使用:str($string,$pattern)
关于 python 模式,
https://docs.pythonlang.cn/release/1.5.1p1/tut/strings.html
http://effbot.org/zone/python-list.htm
关于模式结构
[start:stop:step]
示例,
<?php
$s = "fatihmertdogancan";
echo str($s,"1:9:-2");
echo "<br/>";
echo str($s,"1:-3:-2");
echo "<br/>";
echo str($s,"1:-11:-5");
echo "<br/>";
echo str($s,"1:9:4");
?>
输出,
thetoacn
eht
aom
htan
这是函数 phpfiddle 链接:http://phpfiddle.org/main/code/e82-y5d
或来源;
<?php
function str($str,$pattern){
//[start:stop:step]
//pattern -> ([-]?[0-9]*|\s):([-]?[0-9]*|\s):([-]?[0-9]*|\s)
preg_match("/([-]?[0-9]*|\s?):([-]?[0-9]*|\s?):?([-]?[0-9]*|\s?)/", $pattern, $yakala);
$start = $yakala[1];
$stop = $yakala[2];
$step = $yakala[3];
if(empty($start) && empty($stop) && $step == "-1"){//istisna durum
return strrev($str);
}else if(empty($start) && empty($stop) && isset($step)){//istisna durum
$rev = "";
$yeni = "";
if($step[0] == "-" && $stop != "-1"){$rev = "VAR";}
$atla = abs($step);
for($i = 0; $i <= strlen($str); $i++){
$offset = $i*$atla;
if(isset($str[$offset])){
$yeni = $yeni.$str[$offset];
}
}
if($rev != "VAR"){
return substr($yeni,0,strlen($str)-1);
//"hepsi boş, step dolu o da +";
}else{
return strrev(substr($yeni,0,strlen($str)-1));
//"hepsi boş, step dolu o da -";
}
}
if(empty($start) && empty($stop) && empty($step)){
return $str;
//"hepsi boş";
}else if(empty($start)){
if(isset($stop) && empty($step)){
$rev = "";
if($stop[0] == "-"){$rev = "VAR";}
if($rev != "VAR"){
return substr($str,0,$stop);
//"start ve step boş, stop dolu"
}else{
return strrev(substr($str,0,$stop));
//"start ve step boş, stop -1";
}
}else if(isset($stop) && isset($step)){
$rev = "";
if($stop[0] == "-"){$rev = "VAR";}
$yeni = "";
if($step == 1){
if($rev != "VAR"){
return $str;
//"start boş, stop ve step dolu, step 1";
}else{
return strrev(substr($str,0,abs($stop))); //abs -> mutlak değer (-5 = 5)
//"start boş, stop -, step dolu, step 1";
}
}else{
$atla = abs($step);
for($i = 0; $i <= strlen($str); $i++){
$offset = $i*$atla;
if(isset($str[$offset])){
$yeni = $yeni.$str[$offset];
}
}
if($rev != "VAR"){
return substr($yeni,0,$stop);
//"start boş, step ve stop dolu";
}else{
return strrev(substr($yeni,0,abs($stop)));
//"start boş, step ve stop -";
}
}
}
//start boş değilse
}else if(!empty($start)){
if(isset($stop) && empty($step)){
$rev = "";
if($stop[0] == "-"){$rev = "VAR";}
if($rev != "VAR"){
return substr($str,$start,$stop);
//return "step boş, start ve stop dolu";
}else{
return strrev(substr($str,0,abs($stop)));
//"step boş, start ve stop dolu, stop -";
}
}else if(isset($stop) && isset($step)){
//hepsi dolu
$rev = "";
if($stop[0] == "-"){$rev = "VAR";}
$yeni = "";
if($step == 1){
if($rev != "VAR"){
return substr($str,$start,$stop);
//"hepsi dolu, step 1";
}else{
return substr($str,$start,abs($stop));
//"hepsi dolu, step 1, stop -";
}
}else{
if($stop[0] == "-"){$rev = "VAR";}
$atla = abs($step);
for($i = 0; $i <= strlen($str); $i++){
$offset = $i*$atla;
if(isset($str[$offset])){
$yeni = $yeni.$str[$offset];
}
}
if($rev != "VAR"){
return substr($yeni,$start,$stop);
//"hepsi dolu";
}else{
return strrev(substr($yeni,$start,abs($stop)));
//"hepsi dolu, stop -";
}
}
}
}
}
?>
好作品..
删除文件的扩展名(即使从文件位置字符串中删除)
<?php
$filename = "c:/some dir/abc defg. hi.jklmn";
echo substr($filename, 0, (strlen ($filename)) - (strlen (strrchr($filename,'.'))));
?>
输出:c:/some dir/abc defg. hi
希望对像我一样的人有所帮助.. (^_^)
如果你想获取两个字符串之间的字符串,可以使用这个函数
<?php
function get_between($input, $start, $end)
{
$substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
return $substr;
}
//示例:
$string = "123456789";
$a = "12";
$b = "9";
echo get_between($string, $a, $b);
//输出:
//345678
?>
注意 substr 和 mb_substr 之间存在细微的差异
mb_substr("", 4); 返回空字符串
substr("", 4); 返回布尔值 false
在 PHP 7.1.11 (Fedora 26) 和 PHP 5.4.16 (CentOS 7.4) 中测试
<?php
/**
* string substrpos(string $str, mixed $start [[, mixed $end], boolean $ignore_case])
*
* 如果 $start 是字符串,substrpos 将返回从第一个出现的 $start 位置到 $end 的字符串
*
* 如果 $end 是字符串,substrpos 将返回从 $start 到第一个出现的 $end 位置的字符串
*
* 如果 (string) $start 或 (string) $end 的第一个字符是 '-',则将使用最后一个出现的字符串。
*
* 如果 $ignore_case 为 true,substrpos 将不区分大小写。
* 如果 $ignore_case 为 false(或任何不是 (boolean) true 的内容),函数将区分大小写。
* 以上两者:仅适用于 $start 或 $end 为字符串时。
*
* echo substrpos('This is a string with 0123456789 numbers in it.', 5, '5');
* // 输出 'is a string with 01234';
*
* echo substrpos('This is a string with 0123456789 numbers in it.', '5', 5);
* // 输出 '56789'
*
* echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-string')
* // 输出 's is a string with 0123456789 numbers in it and two '
*
* echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-STRING', true)
* // 输出 's is a string with 0123456789 numbers in it and two '
*
* echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-STRING', false)
* // 输出 's is a string with 0123456789 numbers in it and two strings.'
*
* 警告:
* 由于 $start 和 $end 既可以接受字符串也可以接受整数:
* 如果您在 $str 中搜索的字符或字符串是数字,请将其作为带引号的字符串传递。
* 如果 $end 是 (integer) 0,则将返回空字符串。
* 由于此函数接受负字符串 ('-search_string'):
* 如果您在 $start 或 $end 中使用的字符串是 '-' 或以 '-' 开头,请使用 '\' 对其进行转义。
* 这仅适用于 $start 或 $end 的 *第一个* 字符。
*/
// 如果未定义,则定义 stripos() (PHP < 5)。
if (!is_callable("stripos")) {
function stripos($str, $needle, $offset = 0) {
return strpos(strtolower($str), strtolower($needle), $offset);
}
}
function substrpos($str, $start, $end = false, $ignore_case = false) {
// 使用变量函数
if ($ignore_case === true) {
$strpos = 'stripos'; // 如果未定义,则在上面包含 stripos() (PHP < 5)。
} else {
$strpos = 'strpos';
}
// 如果 end 为 false,则将其设置为 $str 的长度
if ($end === false) {
$end = strlen($str);
}
// 如果 $start 是字符串,则执行必要的操作以将其转换为 substr() 的整数位置。
if (is_string($start)) {
// 如果 $start 以 '-' 开头,则处理到没有更多匹配项为止,并使用找到的最后一个匹配项。
if ($start{0} == '-') {
// 删除 '-'
$start = substr($start, 1);
$found = false;
$pos = 0;
while(($curr_pos = $strpos($str, $start, $pos)) !== false) {
$found = true;
$pos = $curr_pos + 1;
}
if ($found === false) {
$pos = false;
} else {
$pos -= 1;
}
} else {
// 如果 $start 以 '\-' 开头,则删除 '\'。
if ($start{0} . $start{1} == '\-') {
$start = substr($start, 1);
}
$pos = $strpos($str, $start);
}
$start = $pos !== false ? $pos : 0;
}
// 从 $start 到 strlen($str) 裁剪字符串。
$str = substr($str, $start);
// 如果 $end 是字符串,则执行与上面对 $start 执行的操作完全相同的操作。
if (is_string($end)) {
if ($end{0} == '-') {
$end = substr($end, 1);
$found = false;
$pos = 0;
while(($curr_pos = strpos($str, $end, $pos)) !== false) {
$found = true;
$pos = $curr_pos + 1;
}
if ($found === false) {
$pos = false;
} else {
$pos -= 1;
}
} else {
if ($end{0} . $end{1} == '\-') {
$end = substr($end, 1);
}
$pos = $strpos($str, $end);
}
$end = $pos !== false ? $pos : strlen($str);
}
// 由于 $str 已经在 $start 处被裁剪,因此我们可以将 0 作为 substr() 的新 $start 传递
return substr($str, 0, $end);
}
?>
嗯... 这是我编写的脚本,它与 substr 非常相似,但它不接受 html 和 bbcode 用于计数,并且它接受字符串的一部分并显示避免的(html & bbcode)标签;]
特别适用于显示包含 html 和 bbcode 标签的搜索结果的一部分
<?php
/**
* 字符串 csubstr ( 字符串 string, 整数 start [, 整数 length] )
*
* @author FanFataL
* @param string string
* @param int start
* @param [int length]
* @return string
*/
function csubstr($string, $start, $length=false) {
$pattern = '/(\[\w+[^\]]*?\]|\[\/\w+\]|<\w+[^>]*?>|<\/\w+>)/i';
$clean = preg_replace($pattern, chr(1), $string);
if(!$length)
$str = substr($clean, $start);
else {
$str = substr($clean, $start, $length);
$str = substr($clean, $start, $length + substr_count($str, chr(1)));
}
$pattern = str_replace(chr(1),'(.*?)',preg_quote($str));
if(preg_match('/'.$pattern.'/is', $string, $matched))
return $matched[0];
return $string;
}
?>
使用它类似于简单的 substr。
问候 ;]
...
任何来自 Python 世界的人都会习惯使用字符串的“切片索引”来创建子字符串。以下函数模拟基本的 Python 字符串切片行为。(更详细的版本可以支持数组输入以及字符串,以及可选的第三个“步长”参数。)
<?php
function py_slice($input, $slice) {
$arg = explode(':', $slice);
$start = intval($arg[0]);
if ($start < 0) {
$start += strlen($input);
}
if (count($arg) === 1) {
return substr($input, $start, 1);
}
if (trim($arg[1]) === '') {
return substr($input, $start);
}
$end = intval($arg[1]);
if ($end < 0) {
$end += strlen($input);
}
return substr($input, $start, $end - $start);
}
print py_slice('abcdefg', '2') . "\n";
print py_slice('abcdefg', '2:4') . "\n";
print py_slice('abcdefg', '2:') . "\n";
print py_slice('abcdefg', ':4') . "\n";
print py_slice('abcdefg', ':-3') . "\n";
print py_slice('abcdefg', '-3:') . "\n";
?>
$slice 参数可以是单个字符索引,也可以是冒号分隔的范围。范围的起始是包含的,结束是排除的,这可能不直观。(例如,py_slice('abcdefg', '2:4') 生成 'cd' 而不是 'cde')。负范围值意味着从字符串的末尾而不是开头进行计数。范围的起始和结束都可以省略;起始默认为 0,结束默认为输入的总长度。
来自示例的输出
c
cd
cdefg
abcd
abcd
efg
只是一个用于按所需数量切割字符串的小函数。在两个方向上都有效。
<?php
function cutString($str, $amount = 1, $dir = "right")
{
if(($n = strlen($str)) > 0)
{
if($dir == "right")
{
$start = 0;
$end = $n-$amount;
} elseif( $dir == "left") {
$start = $amount;
$end = $n;
}
return substr($str, $start, $end);
} else return false;
}
?>
享受 ;)
快速修剪路径名称末尾可选的尾部斜杠
if (substr( $path, -1 ) == '/') $path = substr( $path, 0, -1 );
我创建了一些用于实体安全分割+长度计数的函数
<?php
function strlen_entities($text)
{
preg_match_all(
'/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
'(?:&(?!\w;)))s',$text,$textarray);
return count($textarray[0]);
}
function substr_entities($text,$start,$limit=0)
{
$return = '';
preg_match_all(
'/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
'(?:&(?!\w;)))s',$text,$textarray);
$textarray = $textarray[0];
$numchars = count($textarray)-1;
if ($start>=$numchars)
return false;
if ($start<0)
{
$start = ($numchars)+$start+1;
}
if ($start>=0)
{
if ($limit==0)
{
$end=$numchars;
}
elseif ($limit>0)
{
$end = $start+($limit-1);
}
else
{
$end = ($numchars)+$limit;
}
for ($i=$start;$i<=$end;$i++)
{
$return .= $textarray[$i];
}
return $return;
}
}
?>
使用 0 作为 substr() 的最后一个参数。
根据示例
<?php $var = substr($var, 4); ?>
运行没有问题。但是
<?php $var = substr($var, 4, 0); ?>
你将一无所获。只是提醒一下。
我需要一个类似于 Oracle 中的 lpad 函数或 SQL 中的 right 函数。
然后我使用了这段代码
<?php
function right($string,$chars)
{
$vright = substr($string, strlen($string)-$chars,$chars);
return $vright;
}
echo right('0r0j4152',4);
?>
结果
4152
------------------------------------------------
这个函数非常简单,我只是想分享一下,也许对某些人有帮助。
致敬,
缩短文件名及其扩展名。
<?php
$file = "Hellothisfilehasmorethan30charactersandthisfayl.exe";
function funclongwords($file)
{
if (strlen($file) > 30)
{
$vartypesf = strrchr($file,".");
$vartypesf_len = strlen($vartypesf);
$word_l_w = substr($file,0,15);
$word_r_w = substr($file,-15);
$word_r_a = substr($word_r_w,0,-$vartypesf_len);
return $word_l_w."...".$word_r_a.$vartypesf;
}
else
return $file;
}
// RETURN: Hellothisfileha...andthisfayl.exe
?>
关于 lmak 的 utf8_substr 函数:模式 '/./u' 不匹配换行符。这意味着从字符串的第 0 个字符到字符串总长度的子字符串将漏掉与字符串中换行符数量相同的尾部字符数量。为了解决这个问题,可以在模式中添加 s 修饰符(PCRE_DOTALL)
<?php
function utf8_substr($str,$start)
{
preg_match_all("/./su", $str, $ar);
if(func_num_args() > 3) {
$end = func_get_arg(2);
return join("",array_slice($ar[0],$start,$end));
} else {
return join("",array_slice($ar[0],$start));
}
}
?>
<?php
// 从另一个字符串的末尾删除字符串
function removeFromEnd($string, $stringToRemove) {
$stringToRemoveLen = strlen($stringToRemove);
$stringLen = strlen($string);
$pos = $stringLen - $stringToRemoveLen;
$out = substr($string, 0, $pos);
return $out;
}
$string = 'picture.jpg.jpg';
$string = removeFromEnd($string, '.jpg');
?>
这里有一个很棒的函数,它使用负偏移量通过 substr 将 IP 地址简单地转换为数字。
如果你想比较一些转换为数字的 IP 地址,你可能需要它。
例如,当使用 ip2country 或从你的网站中消除相同范围的 IP 地址时 :D
<?php
function ip2no($val)
{
list($A,$B,$C,$D) = explode(".",$val);
return
substr("000".$A,-3).
substr("000".$B,-3).
substr("000".$C,-3).
substr("000".$D,-3);
}
$min = ip2no("10.11.1.0");
$max = ip2no("111.11.1.0");
$visitor = ip2no("105.1.20.200");
if($min<$visitor && $visitor<$max)
{ echo '欢迎!'; }
else
{ echo '滚出去!'; }
?>
你可能期望 substr('123456', 6) 返回一个空字符串。但它返回布尔值 FALSE。
手册的返回值部分应该提到这种行为。而它只在参数部分中提到了。
如果你需要一个空字符串而不是布尔值 FALSE,你应该将结果类型强制转换为字符串。
<?php
$a = substr('123456', 6); // 等价于 $a = FALSE
$a = (string) substr('123456', 6); // 等价于 $a = '';
?>
对(最初由“来自阿根廷的 Matias”编写的)str_format_number 函数进行添加。
只是添加了对 $String 比 $Format 短的处理,方法是添加一个边来开始填充,并在 while 循环中添加一个字符串长度。
<?php
function str_format_number($String, $Format, $Start = 'left'){
// 如果要从右到左填充,如果字符串比格式短
if ($Start == 'right') {
$String = strrev($String);
$Format = strrev($Format);
}
if($Format == '') return $String;
if($String == '') return $String;
$Result = '';
$FormatPos = 0;
$StringPos = 0;
while ((strlen($Format) - 1) >= $FormatPos && strlen($String) > $StringPos) {
// 如果是数字 => 存储它
if (is_numeric(substr($Format, $FormatPos, 1))) {
$Result .= substr($String, $StringPos, 1);
$StringPos++;
// 如果不是数字 => 存储字符
} else {
$Result .= substr($Format, $FormatPos, 1);
}
// 掩码中的下一个字符。
$FormatPos++;
}
if ($Start == 'right') $Result = strrev($Result);
return $Result;
}
?>
当使用错误类型的第二个参数时,substr() 不会返回 FALSE,而是返回 NULL,尽管文档说,它应该在错误时返回 FALSE。
在 PHP 5.3 之前,substr() 尝试将第二个参数强制转换为 int,并且不会抛出任何错误。从 PHP 5.3 开始,会抛出警告。
我需要在 html 转换的 utf-8 文本(例如日文文本,如 嬰謰弰脰欰罏)中截取 x 个字符后的字符串。
问题在于符号长度不同,因此我编写了以下函数来处理这个问题。
也许它会有帮助。
<?php
function html_cutstr ($str, $len)
{
if (!preg_match('/\&#[0-9]*;.*/i', $str))
{
$rVal = strlen($str, $len);
break;
}
$chars = 0;
$start = 0;
for($i=0; $i < strlen($str); $i++)
{
if ($chars >= $len)
break;
$str_tmp = substr($str, $start, $i-$start);
if (preg_match('/\&#[0-9]*;.*/i', $str_tmp))
{
$chars++;
$start = $i;
}
}
$rVal = substr($str, 0, $start);
if (strlen($str) > $start)
$rVal .= " ...";
return $rVal;
}
?>
我开发了一个功能,与 jay 的功能有类似的效果。
检查最后一个字符是否为空格。(如果是则以正常方式执行)。
它将字符串分解成一个包含单独单词的数组,效果是... 它将最后一个空格后的所有内容都切掉。
<?php
function limit_string($string, $charlimit)
{
if(substr($string,$charlimit-1,1) != ' ')
{
$string = substr($string,'0',$charlimit);
$array = explode(' ',$string);
array_pop($array);
$new_string = implode(' ',$array);
return $new_string.'...';
}
else
{
return substr($string,'0',$charlimit-1).'...';
}
}
?>
这是一个我编写的脚本,它的作用是用恶意含义的几个部分来分割长单词。这样,表格中的聊天就不会再被拉伸。
<?php
function text($string,$limit=20,$chop=10){
$text = explode(" ",$string);
while(list($key, $value) = each($text)){
$length = strlen($value);
if($length >=20){
for($i=0;$i<=$length;$i+=10){
$new .= substr($value, $i, 10);
$new .= " ";
}
$post .= $new;
}
elseif($length <=15){
$post .= $value;
}
$post .= " ";
}
return($post);
}
// 例如,这将返回:
$output = text("Well this text doesn't get cut up, yet thisssssssssssssssssssssssss one does.", 10, 5);
echo($output); // "Well this text doesn't get cup up, yet thiss sssss sssss sssss sssss sss one does."
?>
我希望它有用.. :)
如果您需要逐个字符解析 utf-8 字符串,请尝试使用此方法。
<?php
$utf8marker=chr(128);
$count=0;
while(isset($string{$count})){
if($string{$count}>=$utf8marker) {
$parsechar=substr($string,$count,2);
$count+=2;
} else {
$parsechar=$string{$count};
$count++;
}
/* 对 parsechar 做你想做的事情 ... ,例如:*/ echo $parsechar."<BR>\r\n";
}
?>
- 它在没有 mb_substr 的情况下工作。
- 它速度很快,因为它在可能的情况下根据索引获取字符,并且避免了任何计数和分割函数。
如果您只需要字符串中的单个字符,则无需使用 substr(),只需使用大括号表示法。
<?php
// 两行代码都会输出第三个字符
echo substr($my_string, 2, 1);
echo $my_string{2};
?>
个人认为大括号语法更快,更易读。
Felipe 的 PHP 中的 JavaScript charAt 等效代码存在一个小错误。有必要比较类型(隐式)或函数返回错误结果。
<?php
function charAt($str,$pos) {
return (substr($str,$pos,1) !== false) ? substr($str,$pos,1) : -1;
}
?>
正如预期,总会有 bug。
<?php
function strlen_entities($text)
{
preg_match_all(
'/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
'(?:&(?!\w;)))s',$text,$textarray);
return count($textarray[0]);
}
function substr_entities($text,$start,$limit=0)
{
$return = '';
preg_match_all(
'/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
'(?:&(?!\w;)))s',$text,$textarray);
$textarray = $textarray[0];
$numchars = count($textarray)-1;
if ($start>=$numchars)
return false;
if ($start<0)
{
$start = ($numchars)+$start+1;
}
if ($start>=0)
{
if ($limit==0)
{
$end=$numchars;
}
elseif ($limit>0)
{
$end = $start+($limit-1);
}
else
{
$end = ($numchars)+$limit;
}
for ($i=$start;($i<=$end && isset($textarray[$i]));$i++)
{
$return .= $textarray[$i];
}
return $return;
}
}
?>
截断浮点数。类似于 Excel 的 TRUNC 函数。
<?php
function truncate_number($val,$decimals=2){
$number=array();
$number=explode(".",$val);
$result=0;
if (count($number)>1){
$result = $number[0] . "." . substr($number[1],0,$decimals);
} else {
$result = $val;
}
unset($number);
return $result;
}
echo truncate_number(99.123456,2); // 结果 = 99.12
echo truncate_number(99.123456,5); // 结果 = 99.12345
echo truncate_number(99.123456,1); // 结果 = 99.1
?>
在 PHP 8 之前,使用零长度字符串或非字符串值作为输入指定长度可能会产生意外的结果。
<?php
foreach (['normal', '', true, false, NULL] as $value) {
echo gettype(substr($value, 0, 10)) . ' ' . substr($value, 0, 10);
}
/*
string normal
boolean
string 1
boolean
boolean
*/
?>
<?php
/**
* 返回并提取原始字符串中由 start 和 length 参数指定的字符串部分。
*
* 此函数类似于函数 substr(),不同之处在于它
* 从原始字符串中删除子字符串
* (按引用传递)。
*
* @param string $string 输入字符串。
* @param integer $start 开始位置(有关解释,请参阅 substr())。
* @param integer $length 长度(有关解释,请参阅 substr())。
* @return mixed 子字符串或 FALSE(有关解释,请参阅 substr())。
**/
function substrex(&$string, $start, $length = PHP_INT_MAX)
{
if($start > strlen($string)) { return false; }
if(empty($length)) { return ''; }
if($start < 0) { $start = max(0, $start + strlen($string)); }
$end = ($length < 0) ?
strlen($string) + $length :
min(strlen($string), $start + $length);
if($end < $start) { return false; }
$length = $end - $start;
$substr = substr($string, $start, $length);
$string = substr($string, 0, $start).substr($string, $end);
return $substr;
}
?>
快捷方式
获取字符串的第一个字符
substr($string, 1)
获取字符串的最后一个字符
substr($string, -1)
删除字符串的第一个字符
substr($string,1)
删除字符串的最后一个字符
substr($string, 0, -1)