目標:讀取文本文件,提取其中所有固定電話與手機號碼,存入 Set<String> 去重。核心 API:
Pattern.compile(regex):編譯正則Matcher.find():尋找下一個匹配子序列Matcher.group():取得匹配到的字串支援格式涵蓋:
86-13xxxxxxxxx、(+86)13xxxxxxxxx、13xxxxxxxxx、8613xxxxxxxxx02-12345678、02-12345678-123、(+86)02-12345678、含分機號public static String phoneRegex() {
// 手機:支援 86、+86、(86)、(+86) 前綴,13/15/18 開頭 11 位
String mobile = "(?:(\\(\\+?86\\))((13|15|18)[0-9])\\d{8})" +
"|(?:86-?((13|15|18)[0-9])\\d{8})" +
"|(?:((13|15|18)[0-9])\\d{8})";
// 固話:支援國碼、區碼、分機
String landline = "(?:(\\(\\+?86\\))(0[0-9]{2,3}-?)?([2-9][0-9]{6,7})(-[0-9]{1,4})?)" +
"|(?:(86-?)?(0[0-9]{2,3}-?)?([2-9][0-9]{6,7})(-[0-9]{1,4})?)";
return "(?:" + mobile + "|" + landline + ")";
}
public static void extractPhones(String text, Set<String> phoneSet) {
Pattern pattern = Pattern.compile(phoneRegex());
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
phoneSet.add(matcher.group());
}
}
public static Set<String> extractFromFile(String filePath) {
Set<String> phones = new HashSet<>();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(filePath), "UTF-8"))) {
String line;
while ((line = br.readLine()) != null) {
extractPhones(line, phones);
}
} catch (IOException e) {
System.err.println("讀取失敗: " + e.getMessage());
}
return phones;
}
public static void main(String[] args) {
Set<String> result = extractFromFile("F:/three.txt");
System.out.println("電話集合:" + result);
}
// 測試文件內容包含多種格式
// 輸出:[86132221, (86)13222144332, 86-13222144332, 32434343, (+86)13222144332, 13888888888]
(?:...) 替代 (...) 減少記憶體佔用\\b 或前後瞄點確保完整匹配Scanner 配合 findInLine此模式易於擴展至:身分證字號、Email、統一編號、信用卡號等結構化資料提取,只需替換正則模式即可復用整個管線。