PHP強化之01 - 字串 String
----- 最後更新【2018-12-7】-----
一、語法
1、字串的4種宣告方式:
在php語法當中,一個字串可以用 4 種方式表達,它們分別是:單引號
、雙引號
、heredoc語法結構
、nowdoc語法結構
。
1)單引號
要表達一個單引號自身,需在它的前面加個反斜線\
來轉義,即\'
。要表達一個反斜線自身,則用兩個反斜線\\
。其它任何方式的反斜線都會被當成反斜線本身,即在單引號字串中的變數和特殊字元的轉義序列將不會被替換(例如\r
或者\n
也是不會被轉義,也是原樣輸出)。
2)雙引號
如果字串是包圍在雙引號" "
中, PHP 將對一些特殊的字元進行解析。
當 PHP 解析器遇到一個美元符號$
{}
來明確變數名的界線。
3)heredoc 語法結構
第三種表達字串的方法是用 heredoc 語法結構:<<<
。在該運算子之後要提供一個識別符號,然後換行。接下來是字串string本身,最後要用前面定義的識別符號作為結束標誌。
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
Warning: 要注意的是結束識別符號這行除了可能有一個分號;
外,絕對不能包含其它字元。這意味著識別符號不能縮排
4)nowdoc 語法結構
就象 heredoc 結構類似於雙引號字串,Nowdoc 結構是類似於單引號字串的。Nowdoc 結構很象 heredoc 結構,但是 nowdoc 中不進行解析操作。這種結構很適合用於嵌入 PHP 程式碼或其它大段文字而無需對其中的特殊字元進行轉義。
一個 nowdoc 結構也用和 heredocs 結構一樣的標記<<<
, 但是跟在後面的識別符號要用單引號括起來,即<<<'EOT'
。Heredoc 結構的所有規則也同樣適用於 nowdoc結構,尤其是結束識別符號的規則。
$str = <<<'EOD' Example of string spanning multiple lines using nowdoc syntax. EOD;
注意:
–單引號比雙引號效率更高。
–當雙引號裡面包含單引號,然後單引號裡面包含變數,這種情況變數也是會正常解析的,同時單引號會原樣輸出。
2、存取和修改字串中的字元:
string 中的字元可以通過一個從 0 開始的下標,用類似 array 結構中的方括號包含對應的數字來訪問和修改,比如$str[42]
。也可用花括號訪問,比如 $str{42}
。可以把 string 當成字元組成的 array。函式 substr()
和 substr_replace()
可用於操作多於一個字元的情況。
3、轉換成字串
1)自動轉換
在一個需要字串的表示式中,會自動轉換為 string。比如在使用函式 echo 或 print 時,或在一個變數和一個 string 進行比較時,就會發生這種轉換。
2)強制轉換
在PHP中,資料型別的轉換屬於強制轉換,且共有三種轉換方式:
一個值可以通過在其前面加上(string)
或用strval()
函式來轉變成字串。
在一個需要字串的表示式中,會自動轉換為 string。也可參考函式settype()
,如settype($var, "string");
。
二、常用函式
1、子字串操作
1)substr—返回字串的子串
string substr( string $string, int $start [, int $length ] )
返回字串 string 由 start 和 length 引數指定的子字串。
substr("abcdef", -3, 1); // 返回 "d"
substr('abcdef', 1, 3); // bcd
2)substr_replace—替換字串的子串
mixed substr_replace ( mixed $string , mixed $replacement , mixed $start [, mixed $length ] )
substr_replace()
在字串 string 的副本中將由 start 和可選的 length 引數限定的子字串使用 replacement 進行替換。返回結果字串。如果 string 是個陣列,那麼也將返回一個數組。
Tip: 在用於長文字隱藏時非常有用(如用...
來替換後面的字串)。
3)str_replace—子字串替換
mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
該函式返回一個字串或者陣列。該字串或陣列是將 subject 中全部的 search 都被 replace 替換之後的結果。
如果沒有一些特殊的替換需求(比如正則表示式),你應該使用該函式替換 ereg_replace()
和 preg_replace()
。
類似的方法有:
preg_replace
- 執行一個正則表示式的搜尋和替換
4)strpos—查詢字串首次出現的位置
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
返回 needle 在 haystack 中首次出現的數字位置。
$newstring = 'abcdef abcdef';
$pos = strpos($newstring, 'a'); //$pos = 0
$pos = strpos($newstring, 'a', 1); // $pos = 7, 不是 0
與該方法類似的還有:
stripos
- 查詢字串首次出現的位置(不區分大小寫)
strrpos
- 計算指定字串在目標字串中最後一次出現的位置
strripos
- 計算指定字串在目標字串中最後一次出現的位置(不區分大小寫)
5)strstr—查詢字串的首次出現;別名也叫strchr
string strstr ( string $haystack , mixed $needle [, bool $before_needle = FALSE ] )
返回 haystack 字串從 needle 第一次出現的位置開始到 haystack 結尾的字串
Note:該函式區分大小寫。如果想要不區分大小寫,請使用stristr()
。
Note:如果你僅僅想確定needle是否存在於haystack中,請使用速度更快、耗費記憶體更少的strpos()
函式。
$email = '[email protected]';
echo strstr($email, '@'); // 列印 @example.com
echo strstr($email, '@', true); // 列印 name,從 PHP 5.3.0 起
與該方法類似的還有:
stristr
- strstr函式的忽略大小寫版本
strrchr
- 查詢指定字元在字串中的最後一次出現
2、字串修改
1)strrev—反轉字串
echo strrev("Hello world!"); // 輸出 "!dlrow olleH"
2)trim—去除字串首尾處的空白字元(或者其他字元)
相關方法:
ltrim
- 刪除字串開頭的空白字元(或其他字元)
rtrim
- 刪除字串末端的空白字元(或者其他字元)。chop—rtrim 的別名
3)從字串中去除 HTML 和 PHP 標記
string strip_tags ( string $str [, string $allowable_tags ] )
該函式嘗試返回給定的字串 str
去除空字元、HTML 和 PHP 標記後的結果。它使用與函式 fgetss() 一樣的機制去除標記。
$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text);
echo "\n";
// 允許 <p> 和 <a>
echo strip_tags($text, '<p><a>');
以上例程會輸出:
Test paragraph. Other text
<p>Test paragraph.</p> <a href="#fragment">Other text</a>
4)字串中大小寫的轉換
strtoupper
- 將字串轉化為大寫
strtolower
- 將字串轉化為小寫
ucfirst
- 將字串的首字母轉換為大寫
ucwords
- 將字串中每個單詞的首字母轉換為大寫
3、字串轉換為陣列
1)str_split—將字串轉換為陣列
array str_split ( string $string [, int $split_length = 1 ] )
將一個字串轉換為陣列。
$str = "Hello Friend";
$arr = str_split($str, 3);
print_r($arr);
以上例程會輸出:
Array
(
[0] => Hel
[1] => lo
[2] => Fri
[3] => end
)
2)preg_split - 通過一個正則表示式分隔字串。
array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )
通過一個正則表示式分隔給定字串.
//使用逗號或空格(包含" ", \r, \t, \n, \f)分隔短語
$keywords = preg_split("/[\s,]+/", "hypertext language, programming");
print_r($keywords);
以上例程會輸出:
Array
(
[0] => hypertext
[1] => language
[2] => programming
)
3)explode—使用一個字串分割另一個字串,返回一個數組。
array explode ( string $delimiter , string $string [, int $limit ] )
此函式返回由字串組成的陣列,每個元素都是 string 的一個子串,它們被字串 delimiter 作為邊界點分割出來。
$str = 'one|two|three|four';
print_r(explode('|', $str));
// 正數的 limit
print_r(explode('|', $str, 2));
// 負數的 limit(自 PHP 5.1 起)
print_r(explode('|', $str, -1));
以上例程會輸出
Array
(
[0] => one
[1] => two
[2] => three
[3] => four
)
Array
(
[0] => one
[1] => two|three|four
)
Array
(
[0] => one
[1] => two
[2] => three
)
相關方法:
implode
- 將一個一維陣列的值轉化為字串
split
- 用正則表示式將字串分割到陣列中
4、固定字串的寬度
1)生成固定寬度字串
方法一: 使用pack()
函式
$str = pack("A35A14A4", "The line of Unix", "Nosee Chan", 2018);
var_dump($str);
在命令列中執行可以看到如下效果:
格式字串A35A14A4
告訴pack()將後面的引數分別轉換為一個包含35個字元用空格填充的字串、 一個14字元用空格填充的字串、以及一個4個字元用空格填充的字串。要在固定寬度記錄中生成空格填充欄位,pack()
為此提供了一個簡潔的解決方案。
方法二: 使用substr()
與str_pad()
結合。
如果非空格的其它字元來填充欄位,則可以考慮用該方法。
string str_pad ( string $input , int $pad_length [, string $pad_string = " " [, int $pad_type = STR_PAD_RIGHT ]] )
使用另一個字串填充字串為指定長度
$data = "The line of Unix";
$str = str_pad(substr($data, 0, 25), 25, '_');
var_dump($str);
2)使文字在指定行長度自動換行。
string wordwrap ( string $str [, int $width = 75 [, string $break = "\n" [, bool $cut = FALSE ]]] )
打斷字串為指定數量的字串
引數說明:str–輸入字串。 width–列寬度。 break–使用可選的break引數打斷字串。 cut–如果cut設定為TRUE,字串總是在指定的width或者之前位置被打斷。因此,如果有的單詞寬度超過了給定的寬度,它將被分隔開來。(參見第二個範例)。當它是FALSE,函式不會分割單詞,哪怕width小於單詞寬度。
$text = "A very long woooooooooooord.";
$newtext = wordwrap($text, 8, "\n", true);
echo "$newtext\n";
以上例程會輸出:
A very
long
wooooooo
ooooord.
$text = "A very long woooooooooooooooooord. and something";
$newtext = wordwrap($text, 8, "\n", false);
echo "$newtext\n";
以上例程會輸出:
A very
long
woooooooooooooooooord.
and
something
5、獲取字串資訊
1)獲取字串長度
int strlen ( string $string )
返回給定的字串 string 的長度。
mixed mb_strlen ( string $str [, string $encoding = mb_internal_encoding() ] )
獲取字串的長度。返回具有 encoding 編碼的字串 str 包含的字元數。 多位元組的字元被計為 1。如果給定的 encoding 無效則返回 FALSE。
$str = '玩去吧a';
echo strlen($str); //輸出10
echo mb_strlen($str); //輸出10
echo mb_strlen($str,'UTF-8'); //輸出4
注意:
在PHP中,字串的長度資訊是直接儲存在zval結構體中的,所以函式strlen()的速度非常快,時間複雜度為O(1)。
2)strval — 獲取變數的字串值
string strval ( mixed $var )
var 可以是任何標量型別(integer/float/string/boolean)。不能將 strval()
用於陣列或物件。
3)is_string — 檢測變數是否是字串
bool is_string ( mixed $var )
如果 var 是 string 則返回 TRUE,否則返回 FALSE。
6、其它常用函式
htmlentities
- 將字元轉換為 HTML 轉義字元
md5_file
- 計算指定檔案的 MD5 雜湊值
md5
- 計算字串的 MD5 雜湊值
sha1
- 計算字串的 sha1 雜湊值
str_repeat
- 重複一個字串
strip_tags
- 從字串中去除 HTML 和 PHP 標記
三、經典例項
1、求出字串"45,8,7,22,34,1,12"所有數字的總合。
<?php
$a = '45,8,7,22,34,1,12';
$a_arr = explode(',',$a); //轉化為陣列
$sum = array_sum($a_arr); //將陣列中的所有值相加
var_dump($sum);
// 執行結果如下:
[email protected]:~$ php demo9.php
int(129)
擴充套件:如果字串中的數字並不是規範地間隔開來的呢,這時要怎麼處理。如,字串"aa56 hello,–12–5,10"。
$str = 'aa56 hello,--12--5,10';
preg_match_all('/([0-9]+)/',$str,$reg); //取出字串中的所有數字
$sum = array_sum($reg[1]); //將陣列中的所有值相加
var_dump($sum);
// 執行結果如下:
[email protected]:~$ php demo9.php
int(83)
注意:如果要相容數字有小數點的情況,則正則表示式改為/([0-9]+\.?[0-9]*)/
2、統計字串"aaa,abcd,xxxdd;dcba"中每個字元出現的次數。
$str ='aaa,abcd,xxxdd;dcba';
$arr = str_split($str); //字串分割成陣列
$res = array_count_values($arr); //統計陣列中所有值出現的次數
var_dump($res);
// 結果如下:
array (size=7)
'a' => int 5
',' => int 2
'b' => int 2
'c' => int 2
'd' => int 4
'x' => int 3
';' => int 1
其它方法參考:
$res = array();
$arr = str_split($str);
foreach ($arr as $key => $val) {
if (!isset($res[$val])) {
$res[$val] = 1;
} else {
$res[$val] += 1;
}
}
//或者:
$res = array();
$arr = str_split($str);
$unique = array_unique($arr);
foreach ($unique as $key => $val) {
$res[$val] = substr_count($str, $val); // 統計某字元在字串中出現的次數
}
3、不使用PHP函式,用方法寫一個反轉字串的函式
這裡很明顯是不能使用PHP的內建函式strrev()
,下面我們來模擬一個strrev方法:
$str = 'abcdefg';
function str_rev($str){
$res = '';
$len = strlen($str);
for($i=$len; $i>0;$i--){
$res .= $str[$i-1];
}
return $res;
}
echo str_rev($str); //輸出為:gfedcba
參考:
1、官方文件:
2、相關書籍:
- 《PHP經典例項》 David Sklar & Adam Trachtenberg