這篇文章主要介紹了Java讀取檔及基於正規表示式的獲取電話號碼功能,結合實例形式詳細分析了正則匹配操作的相關語法及電話號碼匹配的原理與實現技巧,需要的朋友可以參考下
本文實例講述了Java讀取檔案及基於正規表示式的獲取電話號碼功能。分享給大家供大家參考,具體如下:
#1、正規表示式
正規表示式,又稱正規表示法、常規表示法(英文:Regular Expression,在程式碼中常簡寫為regex、regexp或RE),電腦科學的一個概念。正規表示式使用單一字串來描述、匹配一系列符合某個句法規則的字串。在許多文字編輯器裡,正規表示式通常被用來檢索、取代那些符合某個模式的文字。
用到的一些特殊建構正規表示式的意義解析:
? |
當該字元緊接在任何其他限制符(*,+,?,{n},{n,},{n,m})後面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜尋的字串,而預設的 貪婪模式則盡可能多的匹配所搜尋的字串。例如,對於字串“oooo”,“o+?”將符合單一“o”,而“o+”將符合所有“o”。 |
.點 |
#符合「\r\n」以外的任何單一字元。若要匹配包括“\r\n”在內的任何字符,請使用像“[\s\S]”的模式。 |
(pattern) |
匹配pattern並取得此符合。所取得的符合可以從產生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中則使用$0…$9屬性。若要匹配圓括號字符,請使用“”。 |
(?:pattern) |
#符合pattern但不取得符合結果,也就是說這是一個非取得匹配,不進行儲存以供日後使用。這在使用或字元“(|)”來組合一個模式的各個部分是很有用。例如「industr(?:y|ies)」就是比「industry|industries」更簡略的表達式。 |
(?=pattern) |
#正向肯定預查,在任何符合pattern的字串開始處匹配查找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例 如,“Windows(?=95|98|NT|2000)”能符合“Windows2000”中的“Windows”,但不能符合 “Windows3.1”中的“Windows”。預查不消耗字符,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從 包含預查的字符之後開始。 |
(?!pattern) |
#正向否定預查,在任何不符合pattern的字串開始處匹配查找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如 “Windows(?!95|98|NT|2000)”能符合“Windows3.1”中的“Windows”,但不能符合“Windows2000”中 的“Windows”。 |
(?<=pattern) |
#反向肯定預查,與正向肯定預查類似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能符合“2000Windows”中的“Windows”,但不能符合“3.1Windows”中的“Windows”。 |
(? |
反向否定預查,與正向否定預查類似,只是方向相反。例如“(? |
量詞使用
X { n #}? | X# ,剛好 n 次 |
##X { n ,}? | X ,至少 n 次 |
X { n |
2、手机号码
组成
国家区域号-手机号码
手机号码格式比较固定,无非是13x xxxx xxxx或者15x xxxx xxxx再或者18x xxxx xxxx的格式。座机就比较麻烦,比如长途区号变长(3位或者4位)电话号码变长(7位或者8位)有些还需要输入分机号。
通常可以看到解决这个复杂问题的解决方案是手机号和座机号分开。座机号拆分成三段,区号,电话号码+分机号。但是为了表单看起来清爽,设计的时候给了一个“万能”的输入框,给用户输入电话号码或者手机号码。
在这样的一个需求的大前提下,用复杂的正则表达式解决验证的问题是一种快速的解决方案。
首先搞定最容易的手机号码
因为目前开放的号段是130-139, 150-159, 185-189, 180
只考虑移动电话(手机)号码的可以使用下面方法
public static void main(String[] args) { String text = "13522158842;托尔斯泰;test2;13000002222;8613111113313"; Pattern pattern = Pattern.compile("(?<!\\d)(?:(?:1[358]\\d{9})|(?:861[358]\\d{9}))(?!\\d)"); Matcher matcher = pattern.matcher(text); StringBuffer bf = new StringBuffer(64); while (matcher.find()) { bf.append(matcher.group()).append(","); } int len = bf.length(); if (len > 0) { bf.deleteCharAt(len - 1); } System.out.println(bf.toString()); }
只是手机号码可以匹配可以给出下面的匹配正则表达式:
(?:((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})
当我们 加上国家区域号 (86)或者(+86)或者86-或者直接是86,可以使用下面的正则表达式:
"(?:(\\(\\+?86\\))((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})|" +
"(?:86-?((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})|" +
"(?:((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})"
注意 :为了最长得匹配电话号码,需要写成三句,并且相对长的需要放在前面,否则匹配到了之后,后面的就不会匹配了。
3、座机号码
组成:
国家区域号(+86等)-区号-固定电话号码-分机号
三位 区号 的部分
010, 021-029,852(香港)
因为采用三位区号的地方都是8位电话号码,因此可以写成
(010|021|022|023|024|025|026|027|028|029|852)\d{8}
当然不会这么简单,有些人习惯(010) xxxxxxxx的格式,我们也要支持一把,把以上表达式升级成
再看4位区号的城市
这里简单判断了不可能存在0111或者0222的区号,以及电话号码是7位或者8位。
最后是分机号(1-4位的数字)
(?<分机号>\D?\d{1,4})?
以上拼装起来就是:
"(?:(\\(\\+?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})?)"
4、编码实现
实现功能:读取文件,将其中的电话号码存入一个Set返回。
方法介绍:
find()
:尝试查找与该模式匹配的输入序列的下一个子序列。group()
:返回由以前匹配操作所匹配的输入子序列。
①、从一个字符串中获取出其中的电话号码
import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 从字符串中截取出电话号码 * @author zcr * */ public class CheckIfIsPhoneNumber { /** * 获得电话号码的正则表达式:包括固定电话和移动电话 * 符合规则的号码: * 1》、移动电话 * 86+‘-'+11位电话号码 * 86+11位正常的电话号码 * 11位正常电话号码a * (+86) + 11位电话号码 * (86) + 11位电话号码 * 2》、固定电话 * 区号 + ‘-' + 固定电话 + ‘-' + 分机号 * 区号 + ‘-' + 固定电话 * 区号 + 固定电话 * @return 电话号码的正则表达式 */ public static String isPhoneRegexp() { String regexp = ""; //能满足最长匹配,但无法完成国家区域号和电话号码之间有空格的情况 String mobilePhoneRegexp = "(?:(\\(\\+?86\\))((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})|" + "(?:86-?((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})|" + "(?:((13[0-9]{1})|(15[0-9]{1})|(18[0,5-9]{1}))+\\d{8})"; // System.out.println("regexp = " + mobilePhoneRegexp); //固定电话正则表达式 String landlinePhoneRegexp = "(?:(\\(\\+?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})?)"; regexp += "(?:" + mobilePhoneRegexp + "|" + landlinePhoneRegexp +")"; return regexp; } /** * 从dataStr中获取出所有的电话号码(固话和移动电话),将其放入Set * @param dataStr 待查找的字符串 * @param phoneSet dataStr中的电话号码 */ public static void getPhoneNumFromStrIntoSet(String dataStr,Set<String> phoneSet) { //获得固定电话和移动电话的正则表达式 String regexp = isPhoneRegexp(); System.out.println("Regexp = " + regexp); Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(dataStr); //找与该模式匹配的输入序列的下一个子序列 while (matcher.find()) { //获取到之前查找到的字符串,并将其添加入set中 phoneSet.add(matcher.group()); } //System.out.println(phoneSet); } }
②、读取文件并调用电话号码获取
实现方式:根据文件路径获得文件后,一行行读取,去获取里面的电话号码
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * 读取文件操作 * * @author zcr * */ public class ImportFile { /** * 读取文件,将文件中的电话号码读取出来,保存在Set中。 * @param filePath 文件的绝对路径 * @return 文件中包含的电话号码 */ public static Set<String> getPhoneNumFromFile(String filePath) { Set<String> phoneSet = new HashSet<String>(); try { String encoding = "UTF-8"; File file = new File(filePath); if (file.isFile() && file.exists()) { // 判断文件是否存在 InputStreamReader read = new InputStreamReader( new FileInputStream(file), encoding);// 考虑到编码格 BufferedReader bufferedReader = new BufferedReader(read); String lineTxt = null; while ((lineTxt = bufferedReader.readLine()) != null) { //读取文件中的一行,将其中的电话号码添加到phoneSet中 CheckIfIsPhoneNumber.getPhoneNumFromStrIntoSet(lineTxt, phoneSet); } read.close(); } else { System.out.println("找不到指定的文件"); } } catch (Exception e) { System.out.println("读取文件内容出错"); e.printStackTrace(); } return phoneSet; } }
③、测试
public static void main(String argv[]) { String filePath = "F:\\three.txt"; Set<String> phoneSet = getPhoneNumFromFile(filePath); System.out.println("电话集合:" + phoneSet); }
文件中数据:
结果:
电话集合:[86132221, (86)13222144332, 86-13222144332, 32434343, (+86)13222144332, 13888888888]
以上是Java讀取檔案以及取得電話號碼功能(基於正規表示式)的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!