substr
(PHP 4, PHP 5, PHP 7, PHP 8)
substr — 文字列の一部分を返す
説明
文字列 string
の、offset
で指定された位置から length
バイト分の文字列を返します。
パラメータ
string
-
入力文字列。
offset
-
offset
が正の場合、返される文字列は、string
の 0 から数えて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
(string
の長さに依存します) から数えてlength
文字数分となります。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 は、nullable になりました。
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
// 文字列中の 1 文字にアクセスすることも
// "角括弧" を使用することで可能
$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)
参考
- strrchr() - 文字列中に文字が最後に現れる場所を取得する
- substr_replace() - 文字列の一部を置換する
- preg_match() - 正規表現によるマッチングを行う
- trim() - 文字列の先頭および末尾にあるホワイトスペースを取り除く
- mb_substr() - 文字列の一部を得る
- wordwrap() - 指定した文字数で文字列を分割する
- 文字列への文字単位のアクセスと修正
User Contributed Notes 34 notes
For getting a substring of UTF-8 characters, I highly recommend mb_substr
<?php
$utf8string = "cakeæøå";
echo substr($utf8string,0,5);
// output cake#
echo mb_substr($utf8string,0,5,'UTF-8');
//output cakeæ
?>
may be by following functions will be easier to extract the needed sub parts from a string:
<?php
after ('@', 'biohazard@online.ge');
//returns 'online.ge'
//from the first occurrence of '@'
before ('@', 'biohazard@online.ge');
//returns 'biohazard'
//from the first occurrence of '@'
between ('@', '.', 'biohazard@online.ge');
//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 '['
?>
here comes the source:
<?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);
};
?>
Coming to PHP from classic ASP I am used to the Left() and Right() functions built into ASP so I did a quick PHPversion. hope these help someone else making the switch
function left($str, $length) {
return substr($str, 0, $length);
}
function right($str, $length) {
return substr($str, -$length);
}
<?Php
### SUB STRING BY WORD USING substr() and strpos() #####
### THIS SCRIPT WILL RETURN PART OF STRING WITHOUT WORD BREAK ###
$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’ // your description here .
$no_letter = 30 ;
if(strlen($desctiption) > 30 )
{
echo substr($description,0,strpos($description,’ ‘,30)); //strpos to find ‘ ‘ after 30 characters.
}
else {
echo $description;
}
?>
[English]
I created python similar accesing list or string with php substr & strrev functions.
Use: str($string,$pattern)
About the python pattern,
http://docs.python.org/release/1.5.1p1/tut/strings.html
http://effbot.org/zone/python-list.htm
About of pattern structures
[start:stop:step]
Example,
<?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");
?>
Output,
thetoacn
eht
aom
htan
This is function phpfiddle link: http://phpfiddle.org/main/code/e82-y5d
or source;
<?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..
This returns the portion of str specified by the start and length parameters..
It can performs multi-byte safe on number of characters. like mb_strcut() ...
Note:
1.Use it like this bite_str(string str, int start, int length [,byte of on string]);
2.First character's position is 0. Second character position is 1, and so on...
3.$byte is one character length of your encoding, For example: utf-8 is "3", gb2312 and big5 is "2"...you can use the function strlen() get it...
Enjoy it :) ...
--- Bleakwind
QQ:940641
http://www.weaverdream.com
PS:I'm sorry my english is too poor... :(
<?php
// String intercept 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;
}
// Test
$str = "123456???ֽ?123456?ַ???123456??ȡ????";
for($i=0;$i<30;$i++){
echo "<br>".bite_str($str,$i,20);
}
?>
I wanted to work out the fastest way to get the first few characters from a string, so I ran the following experiment to compare substr, direct string access and strstr:
<?php
/* substr access */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
$opening = substr($string,0,11);
if ($opening == 'Lorem ipsum'){
true;
}else{
false;
}
}
$endtime1 = endTimer();
/* direct access */
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 access */
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;
?>
The string was 6 paragraphs of Lorem Ipsum, and I was trying match the first two words. The experiment was run 3 times and averaged. The results were:
(substr) 3.24
(direct access) 11.49
(strstr) 4.96
(With standard deviations 0.01, 0.02 and 0.04)
THEREFORE substr is the fastest of the three methods for getting the first few letters of a string.
If you want to have a string BETWEEN two strings, just use this function:
<?php
function get_between($input, $start, $end)
{
$substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
return $substr;
}
//Example:
$string = "123456789";
$a = "12";
$b = "9";
echo get_between($string, $a, $b);
//Output:
//345678
?>
Be aware of a slight inconsistency between substr and mb_substr
mb_substr("", 4); returns empty string
substr("", 4); returns boolean false
tested in PHP 7.1.11 (Fedora 26) and PHP 5.4.16 (CentOS 7.4)
<?php
/**
* string substrpos(string $str, mixed $start [[, mixed $end], boolean $ignore_case])
*
* If $start is a string, substrpos will return the string from the position of the first occuring $start to $end
*
* If $end is a string, substrpos will return the string from $start to the position of the first occuring $end
*
* If the first character in (string) $start or (string) $end is '-', the last occuring string will be used.
*
* If $ignore_case is true, substrpos will not care about the case.
* If $ignore_case is false (or anything that is not (boolean) true, the function will be case sensitive.
* Both of the above: only applies if either $start or $end are strings.
*
* echo substrpos('This is a string with 0123456789 numbers in it.', 5, '5');
* // Prints 'is a string with 01234';
*
* echo substrpos('This is a string with 0123456789 numbers in it.', '5', 5);
* // Prints '56789'
*
* echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-string')
* // Prints '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)
* // Prints '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)
* // Prints 's is a string with 0123456789 numbers in it and two strings.'
*
* Warnings:
* Since $start and $end both take either a string or an integer:
* If the character or string you are searching $str for is a number, pass it as a quoted string.
* If $end is (integer) 0, an empty string will be returned.
* Since this function takes negative strings ('-search_string'):
* If the string your using in $start or $end is a '-' or begins with a '-' escape it with a '\'.
* This only applies to the *first* character of $start or $end.
*/
// Define stripos() if not defined (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) {
// Use variable functions
if ($ignore_case === true) {
$strpos = 'stripos'; // stripos() is included above in case it's not defined (PHP < 5).
} else {
$strpos = 'strpos';
}
// If end is false, set it to the length of $str
if ($end === false) {
$end = strlen($str);
}
// If $start is a string do what's needed to make it an integer position for substr().
if (is_string($start)) {
// If $start begins with '-' start processing until there's no more matches and use the last one found.
if ($start{0} == '-') {
// Strip off the '-'
$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 {
// If $start begins with '\-', strip off the '\'.
if ($start{0} . $start{1} == '\-') {
$start = substr($start, 1);
}
$pos = $strpos($str, $start);
}
$start = $pos !== false ? $pos : 0;
}
// Chop the string from $start to strlen($str).
$str = substr($str, $start);
// If $end is a string, do exactly what was done to $start, above.
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);
}
// Since $str has already been chopped at $start, we can pass 0 as the new $start for substr()
return substr($str, 0, $end);
}
?>
Hmm ... this is a script I wrote, whitch is very similar to substr, but it isn't takes html and bbcode for counting and it takes portion of string and show avoided (html & bbcode) tags too ;]
Specially usefull for show part of serach result included html and bbcode tags
<?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;
}
?>
Using this is similar to simple substr.
Greatings ;]
...
Drop extensions of a file (even from a file location string)
<?php
$filename = "c:/some dir/abc defg. hi.jklmn";
echo substr($filename, 0, (strlen ($filename)) - (strlen (strrchr($filename,'.'))));
?>
output: c:/some dir/abc defg. hi
Hope it may help somebody like me.. (^_^)