PHP 要快速分割固定格式的文字,可以使用 split、explode 等等,但是若是一串連續的字串,該怎麼做呢?
固定字串例如:20171110235959 (2017年11月10日23點59分59秒)
一般想到最快的就是 preg_match 一行解決,再不然就是 substr,或者直接用陣列存取 $str[0] ~ $str[3] .. 等等,有沒有簡單又快速的解法呢?
PHP 依照「位置」來快速分割固定格式文字
有固定的格式的字串,要依照格式切割,可以考慮使用 sscanf 來做輸入拆解。
- 先說結論:sscanf($str, $format, $mixed...) 參數直接於後面吃進來最推薦
sscanf 的範例程式
preg_match、substr 的範例程式
- <?php
- $str = '20171110235959';
- // preg_match
- preg_match('/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', $str, $m);
- print_r($m);
- // substr
- $y = substr($str, 0, 4) . "\n";
- $m = substr($str, 4, 2) . "\n";
- $d = substr($str, 6, 2) . "\n";
- $h = substr($str, 8, 2) . "\n";
- $i = substr($str, 10, 2) . "\n";
- $s = substr($str, 12, 2) . "\n";
- // string
- $y = $str[0] . $str[1] . $str[2] . $str[3];
- $m = $str[4] . $str[5];
- $d = $str[6] . $str[7];
- $h = $str[8] . $str[9];
- $i = $str[10] . $str[11];
- $s = $str[12] . $str[13];
- ?>
於 PHP 7.0.19 測試 preg_match、substr、sscanf、string 的速度差異
- preg_match:0.11992454528809 秒
- substr:0.026941299438477 秒
- sscanf:0.021934509277344 秒 (註:sscanf 使用 $d 陣列接收)
- sscanf:0.010013580322266 秒 (註:sscanf 使用 list() 接收)
- sscanf:0.0059604644775391 秒 (註:sscanf 直接在 function 後面接收)
- string:0.0050067901611328 秒
雖然 sscanf 沒有比字串陣列存取快,但是寫法簡單易懂,速度也比 substr、regex 的快速(跟 string 也沒差多少),可以參考使用。
註:sscanf 用來 parse access.log 應該也不錯用,於 PHP 官網看到下述範例:
- <?php
- $line = '123.123.123.123 - - [09/Nov/2017:06:25:10 +0800] "GET /2016/01/linux-find-file-directory-perm-2016/ HTTP/1.1" 200 39239 "-" "Mozilla/5.0 (compatible)"';
- $log = [];
- $log['ip'],
- $log['client'],
- $log['user'],
- $log['time'],
- $log['method'],
- $log['uri'],
- $log['prot'],
- $log['code'],
- $log['bytes'],
- $log['ref'],
- $log['agent']
- );
- ?>