樣式驗證

使用 Java 進行資料清理

Dennis Lee

Software Engineer

為什麼需要樣式驗證

  • 資料需遵循特定格式才精確
  • 例如:日期應一致,如 d-MMM-yy
  • 問題:日期格式不一致,如「24/02/22」
  • 解法:用樣式驗證找出不一致格式

 

// 我們從資料集中擷取了這些日期
List<String> dates = Arrays.asList("4-Jan-22", "1-Aug-22", "7-Jul-22", 
                                   "27-Apr-22", "24/02/22");
使用 Java 進行資料清理

三種樣式驗證

  • 完整樣式比對
    • 格式必須完全一致時使用
    • 例如:驗證符合 d-MMM-yy 的日期
  • 樣式搜尋
    • 精確位置不重要時使用
    • 例如:在描述中尋找或檢查產品類別
    • 含有「Dark Chocolate」的產品:「85% Dark Chocolate Bar」、「Dark Chocolate with Nuts」
  • 字元比對
    • 用於快速篩檢資料
    • 例如:檢查數量欄是否含字母(「12.5x」)
使用 Java 進行資料清理

用正規表示式定義樣式

  • 比對日期樣式 d-MMM-yy(如「4-Jan-22」)
  • 正規表示式:\\d{1,2}-[A-Za-z]{3}-\\d{2}

 

\\d{1,2}     // 1-2 位數的日期(如 4 或 27)
-            // 連字號分隔符號

[A-Za-z]{3} // 剛好 3 個字母的月份,如 Jan;可大小寫 - // 連字號分隔符號
\\d{2} // 剛好 2 位數的年份(如 22)
使用 Java 進行資料清理

完整樣式比對

import java.util.regex.Pattern;
// 比對 d-MMM-yy
Pattern datePattern = Pattern.compile("\\d{1,2}-[A-Za-z]{3}-\\d{2}");

for (String date : dates) { // 檢查日期是否符合 datePattern boolean isValid = datePattern.matcher(date).matches(); System.out.println(date + " is valid: " + isValid); }
使用 Java 進行資料清理

完整樣式比對:輸出

4-Jan-22 is valid: true
1-Aug-22 is valid: true
7-Jul-22 is valid: true
27-Apr-22 is valid: true
24/02/22 is valid: false
使用 Java 進行資料清理

樣式搜尋

import java.util.regex.Matcher;
Pattern monthPattern = Pattern.compile("[A-Za-z]{3}"); // 3 個字母,如「Jan」

for (String date : dates) { Matcher matcher = monthPattern.matcher(date); // date 中有無 monthPattern?
if (matcher.find()) { // 若找到樣式則回傳 true
// matcher.group() 回傳比對到的內容 System.out.println("Month found: " + matcher.group()); } else { System.out.println("No month found in: " + date); } }
使用 Java 進行資料清理

樣式搜尋:輸出

Month found: Jan
Month found: Aug
Month found: Jul
Month found: Apr
No month found in: 24/02/22
使用 Java 進行資料清理

字元比對

import com.google.common.base.CharMatcher;
for (String date : dates) {
    boolean isValid =
            // 檢查是否含數字
            CharMatcher.inRange('0', '9').matchesAnyOf(date) &&

// 檢查是否含字母(大小寫) CharMatcher.inRange('a', 'z') .or(CharMatcher.inRange('A', 'Z')).matchesAnyOf(date) &&
CharMatcher.is('-').matchesAnyOf(date); // 檢查是否含連字號 System.out.println(date + " has valid characters: " + isValid); }
使用 Java 進行資料清理

字元比對:輸出

4-Jan-22 has valid characters: true
1-Aug-22 has valid characters: true
7-Jul-22 has valid characters: true
27-Apr-22 has valid characters: true
24/02/22 has valid characters: false
使用 Java 進行資料清理

整合應用

// 定義樣式 d-MMM-yy,如 4-Jan-22
Pattern datePattern = Pattern.compile("\\d{1,2}-[A-Za-z]{3}-\\d{2}");
// 完整樣式比對(date 是否符合 datePattern?)
boolean matchesPattern = datePattern.matcher(date).matches();
// 樣式搜尋(date 是否含月份子字串?)
boolean hasMonth = Pattern.compile("[A-Za-z]{3}").matcher(date).find();
// 字元比對(date 是否含數字?)
boolean hasDigits = CharMatcher.digit().matchesAnyOf(date);
使用 Java 進行資料清理

一起來練習吧!

使用 Java 進行資料清理

Preparing Video For Download...