雜記 › 技術筆記 › 從一堆文字裡挑出手機號碼、電子郵件、身分證,怎麼批次擷取?

從一堆文字裡挑出手機號碼、電子郵件、身分證,怎麼批次擷取?

上個月營運給了我一份從 CRM 匯出的文字,1800 多條客戶回饋,每條前面跟著訂單號和工單號,中間還夾著快遞單號、電子郵件和收件地址。她要的是裡面所有手機號碼,用來核對一份活動名單。我一開始用記事本加手工複製,兩小時才弄了 400 條,還錯了兩次:一次把 11 位的訂單號當成手機號碼抄走,一次漏掉一整行,因為那個號碼緊跟在「電話」兩個字後面、沒有分隔符號。到第三批我才換了做法。

一、手工挑的失敗率比想像中高

做法1800 條的耗時我能查出來的錯誤
記事本逐條複製約 2–3 小時漏行、把訂單號當號碼、貼錯行
試算表軟體裡用公式定位約 40 分鐘欄位黏在同一行時抓不到位置
按規則批次擷取再抽查約 5 分鐘加 10 分鐘抽查剩下的是格式類問題,一眼能看出來

差別不只在快。手工抄寫會產生「漏一行、錯一行」這類最難發現的錯誤,而批次擷取的錯誤是格式性的,可以靠排序和抽查一次性暴露出來。

二、規則擷取的命中是有邊界的

這類工具靠格式匹配,常見的內建規則是:手機號碼取 1 開頭的 11 位數字,電子郵件按 xxx@xxx.xxx,URL 按 http 或 https 開頭,IP 是 IPv4 四段,身分證是 18 位(末位可以是 X),另外還能整出純數字和英文單字。規則一旦是這樣寫的,就一定同時存在誤命中和漏命中:

  • 誤命中:以 1 開頭、正好 11 位的訂單號、快遞單號、條碼片段都會被認成手機號碼。我那次翻車就在這一條。
  • 漏命中:寫成 138-0013-8000 或 +86 13800138000 的,中間有分隔符號就連不成 11 位;市話號碼是區碼加 7–8 位,壓根不在手機號碼規則裡。
  • 歷史格式:15 位的老身分證號不會被 18 位規則命中。資料裡有早年錄入的,必須單獨處理,否則你會以為「這個人沒留電話」。
  • 純數字類型是雙面刃:勾了擷取數字,金額、編號、日期、數量會一起出來,1800 條文字能給你幾千行結果。想不清要哪一類就先別勾它。

三、我實際怎麼做

  1. 把來源文字貼進文字資訊擷取,只勾「手機號碼」。這次提出 1627 條,勾上去重後剩 1541 條,也就是有 86 個號碼在多條回饋裡重複出現——這個差值本身就是個資訊,說明名單裡有同一客戶被錄了兩遍。
  2. 結果按前綴排序再掃一遍,把不像號碼的挑掉。以 100、1300 打頭的長串裡混著十來個訂單號,人工剔了 13 條。
  3. 格式不規整的那部分(帶橫線、帶國際區碼),我先把分隔符號批次去掉重跑一次,比寫複雜規則省事。
  4. 規則拿不準時,先在正規表示式測試裡把匹配醒目標示和分組結果看清楚,確認命中的究竟是哪幾段,再決定要不要用於全量。內建類型覆蓋不到的模式(比如 WO-2026-0001 這種工單號),我是先按數字或英文單字整批提出來,再用批次尋找取代按前綴過濾。
  5. 交付前用隱私資訊遮蔽處理一份對外版本,把手機號碼中段遮掉再發到群組裡,避免完整號碼在聊天記錄裡留下第二份副本。

四、換成日誌情境,同一套做法更省事

後來我把這套流程用在了一次存取日誌排查上。網站前半夜被掃,我從 3 個小時的 access.log 裡先按時間切出可疑段落,再擷取 IPv4 位址,拿到 214 個來源 IP;按出現次數排序後,19 個 IP 佔了絕大部分對 /wp-login.php、/admin/、.env 這類路徑的探測,剩下 195 個基本是正常存取。整個過程不到二十分鐘,其中真正需要人工的部分只有「排序看頭部」那一步。

同一批文字我還順手提了一次 URL,用來核對這些請求打的路徑是不是都在我預期的清單裡。兩次擷取的結果對不上時,通常是日誌欄位格式變了,這個反差本身就是一個不錯的自我檢查訊號,比悶頭信任結果要可靠。

五、幾個容易忽略的細節

  • 擷取結果不是資料真相:格式匹配只說明「這串像手機號碼」。合併回原表要靠訂單號這種不會重複的欄位,不要靠行號,一排序就全錯位。
  • 去重要想清保留哪一條:同一號碼對應不同客戶的情況確實存在,條數變少不代表可以刪來源記錄。
  • 處理位置比功能多少更重要:客戶手機號碼、身分證號這類文字我不會上傳到任何後端,本機處理是我挑工具的第一條。
  • 日誌要先切片:幾十 MB 的 access.log 直接貼進文字框並不現實。我的做法是先按時間取一天、再按狀態碼篩出可疑段落,剩下的量才適合做擷取。
  • 三份留痕:來源文字、擷取結果、人工剔除清單都存著。事後有人問「為什麼少了 86 條」,能立刻答出來,不用重跑。

六、常見疑問

Q:批次擷取的結果一定準嗎?

不。它給出的是「符合格式」的集合,誤命中和漏命中都得靠抽查處理。像 1800 條這種量級,我按 5% 抽查,如果命中集中在同一個前綴就加抽。

Q:為什麼我那條手機號碼沒被提出來?

九成情況是中間有分隔符號或用了全形數字,少數是抄錄時漏了一位、不足 11 位。先把文字統一成半形、去掉多餘符號再跑一次。

Q:能不能只提電子郵件,不混進連結裡的 @?

分開跑:先只勾電子郵件看一份結果,再只勾 URL 看一份,兩份對比就能識別出被當成電子郵件的連結片段。一次勾多項只會讓問題更難定位。

Q:需要自訂規則時怎麼辦?

擷取器本身覆蓋的是內建那幾類,越出這個範圍就得靠正規表示式去確認模式長什麼樣,再用批次尋找取代那類工具按前綴過濾落地。別指望一個環節把所有事做完。

Q:結果一大堆重複怎麼處理?

直接勾擷取裡面的去重;需要再看重複項時,用排序去重類工具把重複的那部分單獨抽出來,往往能順帶查見錄入重複的源頭。

Q:交付給別人時結果該怎麼整理?

原始結果和去重後的結果兩份都留著,中間那份剔除清單也一併交出去。分組我不在表格裡手工篩,而是用排序去重類工具讓重複項自己浮出來,誰被錄了兩遍一目了然。

那兩個小時的手工複製教會我的是:這類活兒真正的成本在「錯誤很難被發現」,而不是「手抄太慢」。批次擷取解決慢的那一半,準確性的另一半要靠抽查、剔除清單和留痕補上。把它當流程的第一步而不是全部,才是它該有的位置。

📎 相關文章

PNG 壓了三遍只減 426 位元組:無損壓縮的真實邊界 2026-10-22 WebP 轉 PNG 後體積漲了幾倍:什麼時候必須轉,怎麼把漲幅壓住 2026-10-22 截圖縮到四分之一,小字糊成一團的三種原因 2026-10-22 同樣裁 300×300,頭像為什麼總偏右下角半格 2026-10-22 按每月 1.7 倍預估 18 個月,腳本和表格為什麼給出兩個數 2026-10-22