当前位置: 移动技术网 > IT编程>开发语言>Java > Java读取文件及基于正则表达式的获取电话号码功能详解

Java读取文件及基于正则表达式的获取电话号码功能详解

2019年07月19日  | 移动技术网IT编程  | 我要评论

本文实例讲述了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”。

(?<!pattern)

反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|nt|2000)windows”能匹配“3.1windows”中的“windows”,但不能匹配“2000windows”中的“windows”。


量词使用

x { n }? x ,恰好 n 次
x { n ,}? x ,至少 n 次
x { n , m}? x ,至少 n 次,但是不超过 m 次

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]

ps:这里再为大家提供2款非常方便的正则表达式工具供大家参考使用:

javascript正则表达式在线测试工具:

正则表达式在线生成工具:

更多关于java算法相关内容感兴趣的读者可查看本站专题:《java正则表达式技巧大全》、《java数据结构与算法教程》、《java操作dom节点技巧总结》、《java文件与目录操作技巧汇总》和《java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网