為了取得 UTF-8 字元的子字串,我強烈推薦使用 mb_substr
<?php
$utf8string = "cakeæøå";
echo substr($utf8string,0,5);
// 輸出 cake#
echo mb_substr($utf8string,0,5,'UTF-8');
// 輸出 cakeæ
?>
(PHP 4, PHP 5, PHP 7, PHP 8)
substr — 傳回字串的一部分
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)
為了取得 UTF-8 字元的子字串,我強烈推薦使用 mb_substr
<?php
$utf8string = "cakeæøå";
echo substr($utf8string,0,5);
// 輸出 cake#
echo mb_substr($utf8string,0,5,'UTF-8');
// 輸出 cakeæ
?>
或許使用以下函式可以更容易從字串中提取所需的子部分
<?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);
};
?>
從經典 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 = ‘你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡 你的描述在這裡’ // 你的描述在這裡。
$no_letter = 30 ;
if(strlen($desctiption) > 30 )
{
echo substr($description,0,strpos($description,’ ‘,30)); //strpos 用於在 30 個字元後尋找 ' '。
}
else {
echo $description;
}
?>
[英文]
我創建了類似於 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..
這會傳回由 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);
}
?>
我想找出從字串中取得前幾個字元最快的方法,所以我執行了以下實驗來比較 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 是取得字串前幾個字母的三種方法中最快的。
如果你想要取得兩個字串「之間」的字串,只要使用這個函式
<?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 位置的字串。
*
* 如果 (字串) $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);
}
?>
嗯...這是我寫的一個腳本,它與 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 類似。
問候 ;]
...
刪除檔案的副檔名(即使是從檔案位置字串中)
<?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 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;
}
?>
請享用 ;)
任何來自 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
快速修剪路徑名稱結尾的可選斜線
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;
}
}
?>
添加到(最初由)「來自阿根廷的 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;
}
?>
使用 0 作為 substr() 的最後一個參數。
依照範例
<?php $var = substr($var, 4); ?>
運作沒有問題。然而
<?php $var = substr($var, 4, 0); ?>
會讓您一無所獲。只是快速提醒一下
我需要剪切 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;
}
?>
我需要一個類似 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;
}
// 回傳: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 'Welcome !'; }
else
{ echo 'Get out of here !'; }
?>
您可能會認為 substr('123456', 6) 會傳回一個空字串。但它實際上會傳回布林值 FALSE。
這種行為應該在手冊的「傳回值」章節中提及。但它只在「參數」章節中提及。
如果您需要的是空字串而不是布林值 FALSE,您應該將結果強制轉換為字串。
<?php
$a = substr('123456', 6); // 等同於 $a = FALSE
$a = (string) substr('123456', 6); // 等同於 $a = '';
?>
當使用錯誤類型的數值作為第二個參數時,substr() 不會傳回 FALSE,而是 NULL,儘管文件說它在錯誤時應該傳回 FALSE。
在 PHP 5.3 之前,substr() 會嘗試將第二個參數強制轉換為 int,且不會拋出任何錯誤。自 PHP 5.3 起,會拋出警告。
我開發了一個與 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;
}
?>
一如往常,總會有錯誤產生
<?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
*/
?>