1. 程式人生 > >PHP強化之01 - 字串 String

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