雜記 › 生活隨筆 › .ß 改大寫後整行多出一格:後綴大小寫頁對 18 行樣本的三檔逐條實測

.ß 改大寫後整行多出一格:後綴大小寫頁對 18 行樣本的三檔逐條實測

整理下載資料夾時把 18 行自造清單貼進後綴大小寫頁三檔各跑一遍:ß 改大寫整串多 1 碼元而位元組不動,點在最末尾的名字記無後綴又記未變化,貼上 20 段只處理 18 個檔名,表格裡的實體串也比複製出去的原串長。

後綴亂了就三檔一起跑

月末清理下載資料夾和照片備份目錄,最亂的是後綴:JPG、jpg、Jpg 同層混著。我把檔名整段貼進後綴大小寫頁,三種檔位各跑一遍——樣本是自己列的一張清單:貼進去 20 段、有效 18 行,名字全是虛構的。

頁面本體實測 211 行、8526 位元組,convertExt 在第 88–113 行,三檔共用同一句按下標拼串。這篇引的數全部出自 後綴大小寫轉換 這一頁的純函式返回值口徑。

有些後綴轉換完整行會變長

clip.ß 的後綴是 ß,1 枚碼元;upper 檔還回 SS 兩枚,整串從 6 碼元漲到 7 碼元,可 UTF-8 位元組數兩邊都是 7。

dot.İ 只有 lower 檔會動:İ 被換成 i 加組合點,後綴 1 碼元變 2,整串碼元 5 到 6、位元組 6 到 7;upper 檔把它摺回原字元,整行不動,記「未變化」。

mix.İß 是三檔分歧的那一行:後綴 2 碼元、整串 6 碼元 8 位元組——upper 給 7 碼元仍 8 位元組,lower 給 7 碼元還 9 位元組,title 一動不動。

落到我那 18 行有效清單上:upper 檔變長 2 行、lower 檔變長 2 行、title 檔變長 1 行。

帶點的名字不一定有後綴

名字長這樣——a.、photo.、..、...、D:\dir.、.bashrc.、archive.tar.,最後一個點全卡在末尾,位置分別是 dot=1、5、1、2、6、7、11。第 92 行只擋 dot<=0,這些全被放行;第 97 行 substring(dot+1) 切出來是長度 0 的空串;第 138 行的 !r.ext 於是把它們和整行沒點的名字歸進同一格——「無後綴」與「未變化」兩個計數器同時加一。7 條各跑 3 檔共 21 次呼叫,返回值與入參逐字元相同。「從最後一個點起算」的判法我單獨寫過一篇,不在這裡復述。

名字dot切出的後綴三檔結果
photo.5空串三檔全同入參
D:\dir.6空串三檔全同入參
.bashrc.7空串三檔全同入參
archive.tar.11空串三檔全同入參
archive.tar.gz10gzgz 照常換檔

行首縮排會被悄悄吃掉

首尾空白在兩處各被剪了一次:process 的第 134 行一次,convertExt 的第 89 行又來一次同一條正則。所以帶 4 個行首空格和 1 個行尾製表符的一行,原始 22 碼元,進入返回值裡 before 已經是 17 碼元。

只餵 convertExt 一處時,13 碼元的 " photo.JPG " 出來 before 是 9 碼元;詞中間的空格剪不掉:20 碼元的 " spaced name .TXT " 剪完 16 碼元,點前面那個空格照舊留著。轉換前列、轉換後列、複製文字這三處,在函式返回值層是同一個剪好的串。

貼進去多少行不等於處理了多少個

清單貼進去 20 段,split(/\r?\n/) 得 20 段,進表只有 18 行:1 個純空格段和 1 個空段在第 135 行被直接跳過。三檔四數:

檔位總檔案數已轉換未變化無後綴
upper187114
lower188104
title188104

已轉換加未變化等於總檔案數,在這張清單三檔都成立:7+11=18、8+10=18。那句「已處理 18 個檔名」報的就是 total,不是貼上段數 20。

表裡的序號也不是貼上位置:把 first.JPG、空行、second.TAR.gz、純空格行、third.7z、尾隨換行這 6 段餵進去,split 得 6 段、總檔案數 3、有效原始行號 1,3,5,表格 # 列(第 158 行的 idx+1)連著排成 1,2,3。檔位切換只在結果已經顯示出來時才自動重跑(第 82–84 行),且第 131 行每次先清空舊結果,三檔四數是三套獨立計數而不是累加。

示例按鈕灌的 7 行(第 190–198 行)是組現成對照。同一段文字,upper 只轉 1 行、lower 轉 5 行、title 轉 6 行,已轉換占比從 14.3% 一路漲到 85.7%。

表格裡看到的和複製出來的不是同一份文字

表格儲存格要過一道 escHtml(第 116–118 行):先 &、再 <、再 >、最後引號,四步連做。於是 all <>&".LOG 這個 12 碼元的 after,在表格裡是 27 碼元的實體串;a<b>.TXT 從 8 碼元變 14;quote".TXT 從 10 碼元變 15。

複製走的是另一條路(第 185 行):只取每行的 after 這一個欄位,用單個換行相連——不帶序號列、不帶轉換前列、不經 escHtml。上面那個 12 碼元的名字,複製出去還是 12 碼元原串。

整串長度條:碼元與位元組兩本賬 clip.ß 原串 6 碼元、7 位元組 clip.SS upper 7 碼元、位元組仍是 7 dot.i 組合點 lower 6 碼元、位元組 6 到 7

圖 1:變長是碼元層的賬,位元組是另一本,兩本不同步

這一頁只產出文字,真要改名字是另一頁 批次重新命名 的事,這篇不替它寫一個字。

文案裡沒提空行,也沒提變長

把工具條目的文案逐條對了一遍,共 14 條判定:一致 6、部分一致 7、衝突 1。五行文案裡沒有「空行」二字,可 20 段貼上對 total 18 的差,正是跳過空行行為給的賬。名字長度沒有上限:200 個 x 加 .JPG 共 204 碼元照樣整串吐回。空文字框、純換行、4 個空格、剪出 5 段全是空行與空格的那一串,都被第 126 行的守衛攔下,只彈「請輸入檔名」;第 153 行那句「無有效資料」在函式層拿不到輸入,清空結果後再點複製,只彈「暫無結果可複製」。

FAQ

Q:檔名一個字沒變,為什麼有的記「已轉換」有的記「未變化」?

判據只看返回串與入參是否逐字元全等。word.ς 的 upper 給 word.Σ,長度沒變、碼位變了,就是已轉換;dot.İ 的 upper、roman.Ⅷ 的 upper 摺疊回原字元,整行不動,記未變化。

Q:多出來的那一個字元是哪來的?

是大小寫映射自己的返回值:ß 大寫還給 SS、İ 小寫還給 i 加一枚組合點,1 碼元進 2 碼元出。這一頁按下標拼串、對返回值不做長度兜底,所以 clip.ß 的 upper 整串從 6 碼元漲到 7,而 UTF-8 位元組數停在 7。

Q:點在最末尾為什麼算無後綴?

dot 大於 0 時 substring 從 dot+1 起切,切出空串,!r.ext 把它們歸到「無後綴」與「未變化」同一格。同為 11 個字元長的名字,archive.tar. 報無後綴,archive.tar.gz 照常轉 gz——差別只在最後一個點後面還有沒有字元。

Q:表格裡的那一行和複製出來的是同一串嗎?

名字不含 &、<、>、引號時是同一串;含就有差——all <>&".LOG 在表格裡是 27 碼元實體,複製出去是 12 碼元原文。螢幕實際渲染未實測,對賬以複製文字為準。

📎 相關文章

四個開關預設開著哪三個:文本集合運算的摺疊口徑、代表元與去重短路實測 2026-11-08 奶奶要連點三下才出來:親戚關係計算器 36 條規則與 11110 條鏈的兜底實測 2026-11-07 口算題卡每張 A4 能排多少題:字號、頁邊距與資訊欄怎麼改分頁 2026-11-03 同一串 23 位元組的內容切換 4 個糾錯等級:這一頁自己寫的二維碼編碼器走到了哪一步 2026-10-30 幀間隔填 137 ms,成品每幀其實停 140 ms:tick 量化、4096 頁填充與跟著第一張走的畫布 2026-10-30