雜記 › 技術筆記 › 13 位連寫只截出 11 位:text-extract 七個內建型別的正則邊界實測

13 位連寫只截出 11 位:text-extract 七個內建型別的正則邊界實測

text-extract 七個內建型別逐檔實測:手機號檔沒有邊界斷言,13 位連寫只截 11 位;URL 檔認協定頭不認裸網域,右括號尾巴會被吞進結果;IPv4 的越界段與前導零一律不命中;數字檔把千分位金額拆成兩行。

貼進去的那串號碼,怎麼少了兩位

13 位連寫的 1381234567890 貼進去,結果框只出 1 條 11 位的 13812345678;換成 21 位連寫也還是 1 條。少掉的那幾位不報錯、不提示。

這是 文字資訊提取 的預設檔。模板實測 6033 位元組、149 行,RULES 裡 7 個型別的正則原文長度各別是 11、46、25、83、75、15、9 個字元,flags 七條全是 g,只有 IP 檔那 83 字元的一條帶邊界斷言。逐檔實測見下表。

型別原文字元數實測能命中實測 0 命中
手機號11联系电话13812345678请查收138-0013-8000
電子郵件46a..b@example.comtest@example.c
URL連結25http://localhost:8080/appftp://example.com/file
IP位址83255.255.255.255192.168.001.1
身分證號7518 個字元的一串17 個字元的一串
數字153.14 與 -3.14全形的 123
英文單字9hello world 出 2 項純中文一行 0 項

手機號檔:夠 11 位就收,不看它從哪裡來

联系电话13812345678请查收 裡號碼緊挨中文、前後沒有分隔符,照樣命中 1 條;反過來,首屏那份 18 位串的中段就截出過 19900101123,+8613800138000 命中的是後 11 位、前綴留在結果外。斷鏈的是分隔符——138-0013-8000 與 138 0013 8000 都 0 命中,11 個全形數字也 0 命中。

無邊界斷言:夠 11 位就收,餘下不成第二條 13 位連寫 命中 11 位,落 2 位 21 位連寫 也只出 1 條 帶分隔符 0 命中 綠色段是命中的 11 位

圖 1:手機號檔三類輸入的實測口徑

電子郵件檔:比寫法本身寬,也比它嚴

46 字元的這條接受加號別名、百分號、連續兩點和整串大寫,a..b@example.com 與 u@-example.com 都整串命中。嚴在末尾:後綴段的量詞是 {2,},所以 test@example 與單字母後綴的 test@example.c 都是 0 命中。

URL 檔:協定頭是硬門檻,尾巴看運氣

25 字元的這條把協定頭寫死,example.com、www.example.com、ftp://example.com/file 全部 0 命中,埠號和查詢字串反倒不設限。排除字元類別裡:全形右括號 U+FF09 在同一條類別裡寫了 2 遍,半形括號與半形分號卻都不在類別裡——所以 (https://example.com/y) 提出來的,是帶一條右括號尾巴的 https://example.com/y)。

IP 檔:七條裡唯一帶邊界斷言的一條

83 字元的這條同時管兩頭。0.0.0.0、255.255.255.255、192.168.1.1 各 1 命中;越界段不給面子,999.1.1.1 與 256.1.1.1 全 0 命中,三段的 1.2.3 也一樣;任何一段帶前導零就整串不中,01.2.3.4 與 192.168.001.1 都拿不到部分結果。它還被前一個字元卡住:ID12192.168.1.1 裡那串合法位址因斷言起不了錨,同樣 0 命中。

數字檔:千分位當分隔符,連字號當負號

15 字元的這條不做數值化,007 和 30 位的長串都逐字元保留。可它把逗號讀成分隔符:1,234.50 端出 2 行 ["1","234.50"],一筆金額拆成兩行;2026-11-05 更熱鬧,端出 3 行 ["2026","-11","-05"],連字號全被當負號,憑空多出兩個不存在的負數。

「英文單字」檔:切的是連續字母串,不是詞

9 字元的這條抓的是連續 ASCII 字母串。https://www.example.com/path 端出 5 項,含協定名和 com;café naïve 被切成 3 段碎片;純中文一行 0 項。它疊上去重還有條吞詞路徑:那行 60 字元的原型鏈方法名,關去重 6 項、開去重只剩 2 項,toString、valueOf、hasOwnProperty、constructor 這 4 個詞被當已見過吞掉。

50 行一起貼:行數恆等於命中數

50 行、1487 字元的混合樣本一次貼入,七類合計命中 265 項、開去重後 160 項(減 105);單檔看 number 從 93 項到 64 項、word 從 133 項到 67 項、url 是 11 項到 11 項(那 11 條互不相同,不是沒生效)。輸出行數恆等於命中數,實測結果值不以換行結尾,空行與無命中行只貢獻 0 行;去重保的是首次出現的位置,不做字典序排序。耗時只測了 Node 側同步呼叫:phone 檔這份樣本連打 200 次累計 8.5 毫秒、平均 0.0427 毫秒每次;把 2 萬個號碼連寫成 220000 字元的單行,出 20000 項用了 1.9 毫秒。這兩個值都不含瀏覽器解析與重繪,瀏覽器端耗時這輪沒測。

同一份 50 行樣本:深色關去重,淺色開去重 phone 10 到 5 email 8 到 7 url 11 到 11 ip 10 到 6 number 93 到 64 word 133 到 67

圖 2:六檔在同一份樣本上的去重前後條數

它不報錯,也不告訴你少了什麼

頁面沒有「未找到」一類提示字串。零命中但輸入非空時,統計照常寫「匹配數量:0」,文字總長仍是輸入本身的長度,切 7 個檔它 7 次都不變;輸入去掉空白後為空時,結果框、高亮區、統計區三個出口一次性清空,連「匹配數量:0」那行也沒了,只剩模板寫的佔位字串「提取結果...」。身分證號只登記兩件事:它在型別清單裡排第 5,命中串恆為 18 個字元,內容層面的任何判斷這輪沒測。

高亮和提取不是同一次匹配

HTTP://EXAMPLE.COM/PATH 在 URL 檔提取 0 項、統計也寫 0,可同一份輸入開了高亮,實測有 1 個區間把這 23 字元整串包住:結果框是空的,兩處匹配走的是不同口徑。本頁七條都只在頁內跑這一次,不涉及把自己程式碼裡的一條寫法反覆複用那種情形——那種情形舊文 正則的標誌位與狀態 寫過。

FAQ

Q:一行裡兩個號碼,為什麼只出一行?

看是不是連寫:兩個不同號連成 22 位會切成 11 加 11;13 位或 21 位只出 1 條,取走 11 位後剩下的湊不出下一條,也不回看重疊區。

Q:結果比原文短,是不是吞了字元?

不一定。電子郵件要後綴至少 2 個字母,缺後綴和單字母後綴都不命中;URL 沒有協定頭直接 0 項;數字檔是把千分位金額拆成 2 行,不是吞掉。

Q:勾上去重為什麼條數掉這麼多?

50 行樣本七類從 265 項到 160 項,光 word 一檔就佔 66;去重只管結果清單,輸出 2 行時高亮區仍可以是 3 個區間。重複怎麼按業務口徑收,可看 批次提取資訊 那篇的記錄。

📎 相關文章

120 個詞槽、15 條整句、1 句寫死的開頭:lorem-ipsum 的詞表清點與重複片段實測 2026-11-05 SVG 預覽的尺寸到底聽誰的:顯示框恆等於容器,刪掉 viewBox 之後 r=1 實測 2 像素 2026-11-05 文字分列後空欄位沒丟:a,,b 照留、列號越界填空、填 0 或 abc 退回全部列實測 2026-11-05 1 GB 文件由 1024 塊拼成:任意大小文件生成的分塊節奏、取消邊界與三種填充位元組 2026-11-04 文件名提取的三處邊界:結尾斜槓只兜一格、查詢串整塊留下、空行靜默消失 2026-11-04