PHP Conference Japan 2024

substr

(PHP 4, PHP 5, PHP 7, PHP 8)

substr傳回字串的一部分

描述

substr(字串 $string, 整數 $offset, ?整數 $length = null): 字串

傳回由 offsetlength 參數指定的 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 無效的字元範圍

如果請求無效的字元範圍,從 PHP 8.0.0 開始,substr() 會回傳空字串;先前會回傳 false

<?php
var_dump
(substr('a', 2));
?>

以上範例在 PHP 8 的輸出結果

string(0) ""

以上範例在 PHP 7 的輸出結果

bool(false)

參見

新增筆記

使用者貢獻的筆記 34 則筆記

Andreas Bur (andreas dot buro at gmail dot com)
15 年前
為了取得 UTF-8 字元的子字串,我強烈推薦使用 mb_substr

<?php
$utf8string
= "cakeæøå";

echo
substr($utf8string,0,5);
// 輸出 cake#
echo mb_substr($utf8string,0,5,'UTF-8');
// 輸出 cakeæ
?>
biohazard dot ge at gmail dot com
11 年前
或許使用以下函式可以更容易從字串中提取所需的子部分

<?php
after
('@', 'biohazard@online.ge');
//回傳 'online.ge'
//從第一個出現的 '@' 開始

before ('@', 'biohazard@online.ge');
//回傳 'biohazard'
//從第一個出現的 '@' 開始

between ('@', '.', 'biohazard@online.ge');
//回傳 'online'
//從第一個出現的 '@' 開始

after_last ('[', 'sin[90]*cos[180]');
//回傳 '180]'
//從最後一個出現的 '[' 開始

before_last ('[', 'sin[90]*cos[180]');
//回傳 'sin[90]*cos['
//從最後一個出現的 '[' 開始

between_last ('[', ']', 'sin[90]*cos[180]');
//回傳 '180'
//從最後一個出現的 '[' 開始
?>

這是原始碼

<?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);
};
?>
greg at apparel dot com
11 年前
從經典 ASP 轉到 PHP,我習慣了 ASP 內建的 Left() 和 Right() 函式,所以我做了一個快速的 PHP 版本。希望這些對其他轉換的人有幫助。

function left($str, $length) {
return substr($str, 0, $length);
}

function right($str, $length) {
return substr($str, -$length);
}
pugazhenthi k
11 年前
<?Php

### 使用 substr() 和 strpos() 取得字串的子字串 #####

### 此腳本將返回不包含斷字的字串部分 ###

$description = ‘你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡’ // 你的描述在這裡。

$no_letter = 30 ;

if(
strlen($desctiption) > 30 )
{
echo
substr($description,0,strpos($description,’ ‘,30)); //strpos 用於在 30 個字元後尋找 ' '。
}
else {
echo
$description;
}

?>
fatihmertdogancan at hotmail dot com
10 年前
[英文]
我創建了類似於 Python 的方式,使用 PHP 的 substr & strrev 函式來存取列表或字串。

用法:str($string,$pattern)

關於 Python 模式,
http://docs.python.org/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 -";
}
}
}
}
}
?>

Good works..
bleakwind at msn dot com
19 年前
這會傳回由 start 和 length 參數指定的 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
// 字串截取 By 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);
}
?>
Petez
17 年前
我想找出從字串中取得前幾個字元最快的方法,所以我執行了以下實驗來比較 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 是取得字串前幾個字母的三種方法中最快的。
nikolai dot wuestemann at t-online dot de
13 年前
如果你想要取得兩個字串「之間」的字串,只要使用這個函式

<?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
?>
Anonymous
7 年前
請注意 substr 和 mb_substr 之間略有不一致之處

mb_substr("", 4); 會傳回空字串

substr("", 4); 會傳回布林值 false

已在 PHP 7.1.11 (Fedora 26) 和 PHP 5.4.16 (CentOS 7.4) 中測試
egingell at sisna dot com
18 年前
<?php

/**
* string substrpos(string $str, mixed $start [[, mixed $end], boolean $ignore_case])
*
* 如果 $start 是字串,substrpos 將會回傳從第一個出現的 $start 位置到 $end 的字串。
*
* 如果 $end 是字串,substrpos 將會回傳從 $start 到第一個出現的 $end 位置的字串。
*
* 如果 (字串) $start 或 (字串) $end 的第一個字元是 '-',將會使用最後一個出現的字串。
*
* 如果 $ignore_case 為 true,substrpos 將不區分大小寫。
* 如果 $ignore_case 為 false (或任何非 (布林值) 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 是 (整數) 0,將會回傳空字串。
* 因為此函式接受負字串 ('-search_string'):
* 如果您在 $start 或 $end 中使用的字串是 '-' 或以 '-' 開頭,請使用 '\' 進行跳脫。
* 這僅適用於 $start 或 $end 的 *第一個* 字元。
*/

// 如果 stripos() 未定義(PHP < 5),則定義 stripos()。
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);
}

?>
fanfatal at fanfatal dot pl
19 年前
嗯...這是我寫的一個腳本,它與 substr 非常相似,但它不會將 html 和 bbcode 納入計數,它會取得字串的一部分並顯示迴避的(html 和 bbcode)標籤 ;]
特別適用於顯示包含 html 和 bbcode 標籤的搜尋結果部分

<?php

/**
* string csubstr ( string string, int start [, int 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 類似。

問候 ;]
...
kaysar in ymail in com
15 年前
刪除檔案的副檔名(即使是從檔案位置字串中)

<?php

$filename
= "c:/some dir/abc defg. hi.jklmn";

echo
substr($filename, 0, (strlen ($filename)) - (strlen (strrchr($filename,'.'))));

?>

輸出結果:c:/some dir/abc defg. hi

希望這能幫助到像我一樣的人.. (^_^)
post [at] jannik - zappe [dot] de
16 年前
一個可以依照指定的數量來剪裁字串的小函式。可以從兩個方向進行。

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

請享用 ;)
slow at acedsl dot com
13 年前
任何來自 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
steve at unicycle dot co dot nz
19 年前
快速修剪路徑名稱結尾的可選斜線

if (substr( $path, -1 ) == '/') $path = substr( $path, 0, -1 );
link
15 年前
我建立了一些用於實體安全分割 + 長度計數的函式

<?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;
}
}
?>
Bradley from California
18 年前
添加到(最初由)「來自阿根廷的 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;
}
?>
pheagey at gmail dot com
12 年前
使用 0 作為 substr() 的最後一個參數。

依照範例
<?php $var = substr($var, 4); ?>

運作沒有問題。然而
<?php $var = substr($var, 4, 0); ?>

會讓您一無所獲。只是快速提醒一下
php_net at thomas dot trella dot de
19 年前
我需要剪切 HTML 轉換後的 UTF-8 文字中的字串(例如日文文字,如 &#23344;&#35632;&#24368;&#33072;&#27440;&#32591;)在 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;
}
?>
Cristianlf
14 年前
我需要一個類似 Oracle 的 lpad 或 SQL 的 right 函式
然後我使用這段程式碼

<?php
function right($string,$chars)
{
$vright = substr($string, strlen($string)-$chars,$chars);
return
$vright;

}

echo
right('0r0j4152',4);
?>

結果
4152
------------------------------------------------
這個函式非常簡單,我只是想分享一下,也許能幫助到某人。

問候,
gkhelloworld at gmail dot com
15 年前
縮短檔名及其擴展名。

<?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;
}
// 回傳:Hellothisfileha...andthisfayl.exe
?>
frank at jkelloggs dot dk
19 年前
關於 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));
}
}
?>
vnonov at gmail dot com / Viktor Nonov
14 年前
<?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');
?>
mar dot czapla at gmail dot com
16 年前
這裡有一個很棒的函數,它使用帶負偏移量的 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
'Welcome !'; }
else
{ echo
'Get out of here !'; }

?>
webmaster at oehoeboeroe dot nl
15 年前
您可能會認為 substr('123456', 6) 會傳回一個空字串。但它實際上會傳回布林值 FALSE。

這種行為應該在手冊的「傳回值」章節中提及。但它只在「參數」章節中提及。

如果您需要的是空字串而不是布林值 FALSE,您應該將結果強制轉換為字串。

<?php
$a
= substr('123456', 6); // 等同於 $a = FALSE
$a = (string) substr('123456', 6); // 等同於 $a = '';
?>
leon weidauer
13 年前
當使用錯誤類型的數值作為第二個參數時,substr() 不會傳回 FALSE,而是 NULL,儘管文件說它在錯誤時應該傳回 FALSE。

在 PHP 5.3 之前,substr() 會嘗試將第二個參數強制轉換為 int,且不會拋出任何錯誤。自 PHP 5.3 起,會拋出警告。
rob NOSPAM at clancentric dot net
19 年前
我開發了一個與 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).'...';
}
}
?>
woutermb at gmail dot com
19 年前
這是我寫的一個腳本,它的作用是將帶有惡意含義的長單字切成幾部分。這樣,表格中的聊天就不會再被拉伸。

<?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."
?>

希望這對您有用.. :)
Quicker
13 年前
如果您需要逐個字元解析 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 的情況下運作
- 它速度很快,因為它會在可能的情況下根據索引抓取字元,並避免任何計數和分割函數
ivanhoe011 at gmail dot com
19 年前
如果您只需要字串中的單個字元,您不需要使用 substr(),只需使用大括號表示法即可

<?php
// 這兩行都會輸出第三個字元
echo substr($my_string, 2, 1);
echo
$my_string{2};
?>

個人認為,使用大括號語法更快且更易讀。
kriskra at gmail dot com
16 年前
felipe 在 php 中撰寫的 javascript charAt 等效函式有個小錯誤。必須同時比較(隱含的)型別,否則函式會回傳錯誤的結果。
<?php
function charAt($str,$pos) {
return (
substr($str,$pos,1) !== false) ? substr($str,$pos,1) : -1;
}
?>
link
15 年前
一如往常,總會有錯誤產生

<?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;
}
}
?>
Nadeem
10 年前
截斷浮點數。類似 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
?>
robinhood70 at live dot ca
3 年前
在 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
*/
?>
To Top