將 "Reversing a string by word" 變為 "word by string a Reversing" 是典型的單詞反轉需求。本文對比字符反轉(strrev)與單詞反轉的區別,給出標準實現與邊界處理。
<?php
function reverseWords(string $sentence): string
{
// 1. 按空白字符分割(支援多空格、Tab、換行)
$words = preg_split('/\s+/', trim($sentence), -1, PREG_SPLIT_NO_EMPTY);
// 2. 反轉數組順序
$words = array_reverse($words);
// 3. 用單個空格連接
return implode(' ', $words);
}
echo reverseWords("Reversing a string by word"); // word by string a Reversing
echo reverseWords(" multiple spaces\tand\nnewlines "); // newlines and spaces multiple
<?php
$str = "Hello World";
// 字符級反轉
echo strrev($str); // dlroW olleH
// 單詞級反轉
echo reverseWords($str); // World Hello
| 輸入 | 預期輸出 | 關鍵處理 |
|---|---|---|
空字符串 "" | "" | trim 後 preg_split 返回 [],implode 得空串 |
純空白 " " | "" | PREG_SPLIT_NO_EMPTY 過濾空段 |
多種空白 "a\tb\nc" | "c b a" | /\s+/ 匹配任意空白字符 |
標點附著 "Hello, world!" | "world! Hello," | 視為單詞一部分(若需分離標點需 NLP 分詞) |
Unicode 空白 "a\u{3000}b" | "b a" | /\s+/u 加 u 修飾符支援 Unicode |
<?php
function reverseWordsKeepSpacing(string $sentence): string
{
// 使用 preg_split 捕獲分隔符
$parts = preg_split('/(\s+)/', $sentence, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
// $parts 交替包含單詞和空白段
$words = [];
$spaces = [];
foreach ($parts as $i => $part) {
if ($i % 2 === 0) $words[] = $part;
else $spaces[] = $part;
}
$words = array_reverse($words);
// 重新交織
$result = '';
foreach ($words as $i => $word) {
$result .= $word;
if (isset($spaces[$i])) $result .= $spaces[$i];
}
return $result;
}
echo reverseWordsKeepSpacing(" Hello World "); // " World Hello "
strrev:~3 ms(C 級函數,極快)explode + array_reverse + implode:~18 mspreg_split + array_reverse + implode:~45 ms(正則開銷)保留空白版:~60 ms單詞反轉:用
preg_split('/\s+/u', trim($s)) + array_reverse + implode(' '),清晰、正確、支援 Unicode。
字符反轉:直接strrev()。
保留格式反轉:罕見需求,用捕獲分隔符版本。
中文分詞反轉:單詞邊界不明確,需引入jieba-php、scws等分詞庫,非簡單空格分割可解決。
搞清「反轉什麼粒度」,選對函數組合,才能寫出語義正確、邊界安全的代碼。