PHP 依照「位置」來快速分割固定格式文字

PHP 要快速分割固定格式的文字,可以使用 split、explode 等等,但是若是一串連續的字串,該怎麼做呢?

固定字串例如:20171110235959 (2017年11月10日23點59分59秒)

一般想到最快的就是 preg_match 一行解決,再不然就是 substr,或者直接用陣列存取 $str[0] ~ $str[3] .. 等等,有沒有簡單又快速的解法呢?

PHP 依照「位置」來快速分割固定格式文字

有固定的格式的字串,要依照格式切割,可以考慮使用 sscanf 來做輸入拆解。

  • 先說結論:sscanf($str, $format, $mixed...) 參數直接於後面吃進來最推薦

sscanf 的範例程式

  1. <?php
  2. $str = '20171110235959';
  3. // 陣列接收
  4. $d = sscanf($str, '%4d%2d%2d%2d%2d%2d');
  5. print_r($d);
  6. // 使用 list() 接收
  7. list($y, $m, $d, $h, $i, $s) = sscanf($str, '%4d%2d%2d%2d%2d%2d');
  8. // 直接於 sscanf() 後面接收
  9. sscanf($str, '%4d%2d%2d%2d%2d%2d', $y, $m, $d, $h, $i, $s); // 同上 list() 一樣結果
  10. ?>

preg_match、substr 的範例程式

  1. <?php
  2. $str = '20171110235959';
  3. // preg_match
  4. preg_match('/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', $str, $m);
  5. print_r($m);
  6. // substr
  7. $y = substr($str, 0, 4) . "\n";
  8. $m = substr($str, 4, 2) . "\n";
  9. $d = substr($str, 6, 2) . "\n";
  10. $h = substr($str, 8, 2) . "\n";
  11. $i = substr($str, 10, 2) . "\n";
  12. $s = substr($str, 12, 2) . "\n";
  13. // string
  14. $y = $str[0] . $str[1] . $str[2] . $str[3];
  15. $m = $str[4] . $str[5];
  16. $d = $str[6] . $str[7];
  17. $h = $str[8] . $str[9];
  18. $i = $str[10] . $str[11];
  19. $s = $str[12] . $str[13];
  20. ?>

於 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 官網看到下述範例:

  1. <?php
  2. $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)"';
  3. $log = [];
  4. $n = sscanf(trim($line), '%s %s %s [%[^]]] "%s %s %[^"]" %d %s "%[^"]" "%[^"]"',
  5. $log['ip'],
  6. $log['client'],
  7. $log['user'],
  8. $log['time'],
  9. $log['method'],
  10. $log['uri'],
  11. $log['prot'],
  12. $log['code'],
  13. $log['bytes'],
  14. $log['ref'],
  15. $log['agent']
  16. );
  17. ?>

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料