精华内容
下载资源
问答
  • 本文主要涉及以下内容:正则表达式基础什么是正则表达式不管是使用Windows的搜索...正则表达式可以理解为超复杂的通配符,可以比通配符匹配的更为精准,正规一点的说法就是使用单个字符串来描述、匹配一系列符合某个...
    0b6d8cf3e3cf0339632f79172abad6c7.png532ddbd2ce5314306c5c4c5f1d02d069.png

    本文主要涉及以下内容:

    84ff149483daa397524790c329c1e9a6.pnga3f1f7fb099d57885c9cd636117963ff.png

    正则表达式基础

    什么是正则表达式

    不管是使用Windows的搜索工具,还是在word文档里面的查找和替换,肯定都用过*?这种通配符

    如果想要在某个目录下找到自己写的笔记,我最常用的方法就是*.md就可以找到当前文件夹下所有的Markdown文件了;

    正则表达式可以理解为超复杂的通配符,可以比通配符匹配的更为精准,正规一点的说法就是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。

    比如密码的限制(8位以上16位以内,不能出现特殊字符等等)、邮箱的格式,距离生活近一点的就是某手上的"你个萌萌",王者荣耀上的"你个**"。这些都是正则表达式的运用。

    字符类

    但是如果想查到一组限定的字符,比较原音字母(a, e, i, o, u),特殊字符(*, &, %, @)这怎么弄呢?

    在正则表达式中使用[]将一组字符包裹起来,就到达了自己的需要,例如原音字符[aeiou],特殊字符[*&%@]即可完美的匹配任意一个!

    元字符

    如果想要匹配.?*这些符号,可以使用转义字符\,比如\.,其他元字符如下

    32413b57d73375dc8eb8ad383e9c519b.png

    正则中的重复

    192a4fe7bb1686f81d1f565d1a1a64ef.png

    分支条件

    |把不同的规则分隔开,从左到右地测试每个条件,如果满足了某个分支的话,就不会去再管其它的条件了(就是如果有一个表达式为true,就不会执行后面的表达式,如果一直为false就一直执行)

    来一个小栗子:中国地区的手机号样式一般如下

    b42c269bf3c53e3570d93ace3cd76c73.png

    上面基本罗列出来了所有的手机号样式,现在假设有一个文本框,里面只能输入这种手机号,如果不符合格式,就会给出提示。正则表达式可以这样写?

    b0e1d1b79d140d694b70db2e597b6e0a.png

    首先这是一个有分支条件的式子,第一个式子依次是表示字符串的开始和结尾^ $,然后是'\('转义(,0,数字出现2到3次转义)数字出现7到8次。第二个式子依次是表示字符串的开始和结尾^ $,然后是0,数字出现2到3次[-\s]{1}-符号或空格符号出现出现1次,数字出现7到8次。这样再配合编程语法就可以完成这样一个限制输入的内容!

    贪婪与懒惰

    贪婪(尽可能多)

    a.*f(abcdefbcedf) → abcdefbcedf

    懒惰(尽可能少)

    a.*?f(abcdefbcedf) → abcdef

    9cb4096b148223bdc4965c502c48dd55.png

    分组

    在正则表达式中使用()进行分组,分组之后就可以对某个分组进行操作,比如重复某个分组,对引用某个分组,对某个分组进行命名,语法格式如下:

    d1e71c5fef09d8e1ce36097b862d8cdf.png

    使用小括号进行分组,?P进行命名,如果想在后面进行引用的话使用(?P=name)来进行引用,示例如下

    4ad772c3330402650a6e2366ce3aa588.png

    这样就可以完成一个简单的匹配IP地址的表达式!

    8d607f8e1c3e59de33810eb74627a6e8.png

    零宽断言

    零宽断言就跟它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已。

    作用是给指定位置添加一个限定条件,用来规定此位置之前或者之后的字符必须满足限定条件才能使正则中的字表达式匹配成功。

    零宽度正预测先行断言

    (?=exp) 零宽度正预测先行断言,自身出现的位置的后面能匹配表达式exp,例如想要匹配以ing结尾的单词显示又不需要ing,这个时候就需要零宽度正预测先行断言;这么说比较抽象,直接上栗子

    ae6e4066eebca8a340b31228ab067468.png

    不匹配每个单词的ing的正则表达式?

    c1cbb593fd45d3614c6f9a6860443c58.png81209d00d071ab95625bb02609703a83.png

    零宽度正回顾后发断言

    (?<=exp)零宽度正回顾后发断言,自身出现的位置的前面能匹配表达式exp,就是匹配前面的是某个字符且不匹配他,举个栗子

    b646da4a7265167220ebebfe175b08ee.png

    匹配re开头的单词不匹配re,此处用到的软件为RegexBuddy

    6959e53cdedb8346bd6d26e93646c122.png

    负向零宽断言

    (?!exp)零宽度负预测先行断言,断言此位置的后面不能匹配表达式exp,简单点说就是后面不能出现某个东东,我们来查找包含Windows的字符串,但是Windows后面不能是10

    c8f4b17fd6f09366a2b4bfe7ce726a26.png

    这里仅仅查找出来了3个!

    零宽度负回顾后发断言

    (?零宽度负回顾后发断言,来断言此位置的前面不能匹配表达式exp,Python中提供的re模块使Python拥有全部正则表达式的功能!

    d1739597de70761a1c58197b7c744f4d.png

    re模块

    正则表达式的修饰符

    c62ec12e580f5c24e87cecc803ad57f1.png

    查找单个匹配项:map

    re.match 如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的匹配对象 。如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。语法格式如下:

    9e447e26b6320716dfdd766ab38db08b.png

    pattern是匹配的正则表达式,string是要匹配的字符串。flags是标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

    匹配成功re.match方法返回一个匹配的对象,否则返回None,示例代码如下

    3f843fc1ce9d45e64f0469382500ec4c.png

    开局导入re模块,r""表示为一个正则表达式,因为string2中间出现了一个数字5 所以不匹配!

    查找单个匹配项:group

    re.group是从Match对象中获取结果的,不过不分组默认为0,分组索引则从0开始(0是完整的一个匹配),如果多个分组,则第一个分组是1;也可以为其命名使用,示例代码如下

    f527faaf96bf5d68f04d583685121513.png

    查找单个匹配项:search

    re.search 扫描整个字符串找到匹配样式的第一个位置,并返回一个相应的匹配对象 。如果没有匹配,就返回一个 None ;注意这和找到一个零长度匹配是不同的。语法结构和match是一样的,示例代码如下

    b78402efc93b701296034e76cb20bfd3.png

    两者的区别为:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回 None,而re.search匹配整个字符串,直到找到一个匹配。

    查找单个匹配项:fullmatch

    re.fullmatch如果整个 string 匹配这个正则表达式,就返回一个相应的匹配对象 。否则就返回 None ;注意跟零长度匹配是不同的。语法格式跟上面的也是一样的,示例代码如下

    2b1e0fbd9921d5e732f2ef97c4704be2.png

    三者的区别:

    • match:字符串开头匹配

    • search:查找任意位置的匹配项

    • fullmatch:整个字符串要与正则表达式完全匹配

    匹配对象

    匹配对象总是有一个布尔值 True。如果没有匹配的话match()  search() 返回 None 所以可以简单的用 if 语句来判断是否匹配,示例代码

    f6c59694e45b8fc8ae39dd1e5c339f64.png

    查找多个匹配对象——compile

    re.compile将正则表达式的样式编译为一个正则对象,可以用于匹配,语法结构?

    3feb6e71c38a4fe676ce7da305f64692.png

    pattern是匹配的正则表达式,flags是标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

    查找多个匹配对象——findall

    re.findall在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。与match 和 search 不同的是 match 和 search 是匹配一次 findall 匹配所有。语法结构为

    bd8419b9eb79e667816323e432666a92.png
    • string 待匹配的字符串。

    • pos 可选参数,指定字符串的起始位置,默认为 0。

    • endpos 可选参数,指定字符串的结束位置,默认为字符串的长度

    查找多个匹配对象——finditer

    pattern 在 string 里所有的非重复匹配,返回为一个迭代器保存了匹配对象 。string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。语法结构同match,示例代码

    d0de6da5d0cda07977cd482d287f15e4.png

    如果有超大量的匹配项的话,返回finditer的性能要优于findall,这就是列表和迭代器的区别,在第二十一天的Python中的生成式和生成器会提到!

    分割——split

    re.split方法按照能够匹配的子串将字符串分割后返回列表,语法结构

    e00db0294211bbf7099d4e7f9d8198c9.png
    • pattern:分隔的正则表达式

    • string:分隔的文本

    • maxsplit:分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。

    • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

    示例代码

    3065c7b02869d9b31f1c3b752dc6088a.png

    str模块的split不同的是,re模块的split支持正则

    替换——sub

    re.sub用于替换字符串中的匹配项,语法结构如下

    6252fe637fa319bd00974409ce247864.png
    • pattern : 正则中的模式字符串。

    • repl : 替换的字符串,也可为一个函数。

    • string : 要被查找替换的原始字符串。

    • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

    • flags : 编译时用的匹配模式,数字形式。

    到这里就可以完成一个某手的评论区,修改不良评论的小案例

    a38a29e51fc96f458d747475d6efad4b.pngf3c8fa611710253b427e57ca7345004c.gif

    替换——subn

    行为与 sub() 相同,但是返回一个元组 (字符串, 替换次数).

    escape

    re.escape(pattern)转义 pattern 中的特殊字符。例如正则里面的元字符,示例代码如下

    8341f45d6d10a9107adaf79f23aaf9fb.png

    注:任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的,不过容易出现错误,手动转义比较好!

    purge

    re.purge()用于清除正则表达式的缓存。

    e5a8376a2a3273fa8320dff10c97c7b3.png821f8c2cc99c0d94d42648fee8b9abf6.gifa0c792b7d4e05261898c1ee3b5984c22.pngc319eaa0dd70d9973dca863fd970941e.gifbd0da17ded3a0ff4d4ab39ac00fa9428.png1446b214059c9cee5552256ab6c3efc2.pngf87ca5fbb968ed33c2ec0fd57731ee78.pngc4f8fff6d78b8bac2f4be26b7385f5da.pnge74da1ead0197aee55e657470818c327.png
    展开全文
  • 本资源文件是我自己总结的,其中包括5个类,这5个类的代码基本...用正则表达式替换字符串内容,使用正则表达式切割字符串,字符串匹配,将字符串“<msg>ha>ve modif”中的>替换为>将<替换为<将&替换为2. 等等情况!
  • replaceAll()方法接受一个正则表达式和字符串作为参数,并且在当前字符串与给定正则表达式匹配的内容,在匹配的情况下,替换字符串匹配的元素。使用replaceAll()方法从文件中删除特定的字符串-以字符串形式检索文件...

    replaceAll()方法接受一个正则表达式和字符串作为参数,并且在当前字符串与给定正则表达式匹配的内容,在匹配的情况下,替换字符串匹配的元素。

    使用replaceAll()方法从文件中删除特定的字符串-以字符串形式检索文件的内容。

    使用方法将所需的单词替换为空的String replaceAll()。

    再次将结果字符串重写到文件中。

    示例import java.io.File;

    import java.io.FileNotFoundException;

    import java.io.PrintWriter;

    import java.util.Scanner;

    public class StringExample {

    public static String fileToString(String filePath) throws Exception{

    String input = null;

    Scanner sc = new Scanner(new File(filePath));

    StringBuffer sb = new StringBuffer();

    while (sc.hasNextLine()) {

    input = sc.nextLine();

    sb.append(input);

    }

    return sb.toString();

    }

    public static void main(String args[]) throws FileNotFoundException {

    String filePath = "D://sample.txt";

    String result = fileToString(filePath);

    System.out.println("Contents of the file: "+result);

    //用所需的单词替换单词

    result = result.replaceAll("\\bNhooo\\b", "");

    //重写文件内容

    PrintWriter writer = new PrintWriter(new File(filePath));

    writer.append(result);

    writer.flush();

    System.out.println("替换所需单词后的文件内容:");

    System.out.println(fileToString(filePath));

    }

    }

    输出结果Contents of the file: Hello how are you welcome to Nhooo

    替换所需单词后的文件内容:

    Hello how are you welcome to

    展开全文
  • 正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。用到的一些特殊构造正则表达式的意义解析:?当该字符 紧跟在...

    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,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 voidmain(String[] args) {

    String text= "13522158842;托尔斯泰;test2;13000002222;8613111113313";

    Pattern pattern= Pattern.compile("(?

    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():返回由以前匹配操作所匹配的输入子序列。

    1》、从一个字符串中获取出其中的电话号码

    importjava.util.HashSet;importjava.util.Set;importjava.util.regex.Matcher;importjava.util.regex.Pattern;/*** 从字符串中截取出电话号码

    *@authorzcr

    **/

    public classCheckIfIsPhoneNumber

    {/*** 获得电话号码的正则表达式:包括固定电话和移动电话

    * 符合规则的号码:

    * 1》、移动电话

    * 86+‘-’+11位电话号码

    * 86+11位正常的电话号码

    * 11位正常电话号码a

    * (+86) + 11位电话号码

    * (86) + 11位电话号码

    * 2》、固定电话

    * 区号 + ‘-’ + 固定电话 + ‘-’ + 分机号

    * 区号 + ‘-’ + 固定电话

    * 区号 + 固定电话

    *@return电话号码的正则表达式*/

    public staticString 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 +")";returnregexp;

    }/*** 从dataStr中获取出所有的电话号码(固话和移动电话),将其放入Set

    *@paramdataStr 待查找的字符串

    *@paramphoneSet dataStr中的电话号码*/

    public static void getPhoneNumFromStrIntoSet(String dataStr,SetphoneSet)

    {//获得固定电话和移动电话的正则表达式

    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);

    }

    }

    2、读取文件并调用电话号码获取

    实现方式:根据文件路径获得文件后,一行行读取,去获取里面的电话号码

    importjava.io.BufferedReader;importjava.io.File;importjava.io.FileInputStream;importjava.io.InputStreamReader;importjava.util.ArrayList;importjava.util.HashSet;importjava.util.List;importjava.util.Set;/*** 读取文件操作

    *

    *@authorzcr

    **/

    public classImportFile

    {/*** 读取文件,将文件中的电话号码读取出来,保存在Set中。

    *@paramfilePath 文件的绝对路径

    *@return文件中包含的电话号码*/

    public static SetgetPhoneNumFromFile(String filePath)

    {

    Set phoneSet = new HashSet();try{

    String encoding= "UTF-8";

    File file= newFile(filePath);if (file.isFile() &&file.exists())

    {//判断文件是否存在

    InputStreamReader read = newInputStreamReader(new FileInputStream(file), encoding);//考虑到编码格

    BufferedReader bufferedReader = newBufferedReader(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();

    }returnphoneSet;

    }

    }

    3》、测试

    public static voidmain(String argv[])

    {

    String filePath= "F:\\three.txt";

    Set phoneSet =getPhoneNumFromFile(filePath);

    System.out.println("电话集合:" +phoneSet);

    }

    文件中数据:

    46107b593eb2174fa2c321a3f082c6e6.png

    结果:

    电话集合:[86132221, (86)13222144332, 86-13222144332, 32434343, (+86)13222144332, 13888888888]

    致谢:感谢您的阅读!

    展开全文
  • 本文实例讲述了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 , 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("(?

    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 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 getPhoneNumFromFile(String filePath)

    {

    Set phoneSet = new HashSet();

    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 phoneSet = getPhoneNumFromFile(filePath);

    System.out.println("电话集合:" + phoneSet);

    }

    文件中数据:

    87d4af3432c94c5ef1879b0de032dc00.png

    结果:

    电话集合:[86132221, (86)13222144332, 86-13222144332, 32434343, (+86)13222144332, 13888888888]

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

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

    展开全文
  • Java字符串替换方法用于用其他一些字符串替换部分字符串。...public String replace(CharSequence target, CharSequence replacement):此方法用替换字符串替换此字符串的每个子字符串并返回它。请注意,替换..
  • JAVA 正则表达式

    热门讨论 2010-01-15 11:16:37
    Java正则表达式入门 众所周知,在程序开发中,难免会遇到需要匹配、查找、替换、判断字符串的情况发生,而这些情况有时 又比较复杂,如果用纯编码方式解决,往往会浪费程序员的时间及精力。因此,学习及使用正则...
  • 正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。  用到的一些特殊构造正则表达式的意义解析: ? ...
  • 我能帮您从一个文本文件中找出所有 指定规律的字符,并且还能替换结果中的某个指定字符,最后再打印出来。这里的“规律”是指 匹配正则表达式。##怎么实现的?文本文件的读取是通过BufferedReader和FileReader来实现...
  • java正则表达式的入门

    2014-11-04 19:44:44
    正则表达式,可用来描述或匹配一系列符合某个句法规则的字符串的单个字符串。所以借助正则表达式,能够对含有各种字符歌词lrc文件提取有效信息,并归类保存。一个正则表达式通常被称为一个模式(pattern),为用来描述...
  • Java.util.regex包下的Pattern和Matcher这两个类提供了通过正则表达式来匹配查询,甚至替换的功能。那么我们接下来就举个栗子吧 : 栗子1:查找文件中以img_数字.png格式的字符串,并在前面添加路径: /test/img/ ...
  • String类的split()方法。...String类的replaceAll()方法接受两个表示正则表达式的字符串和一个替换String,并将匹配的值替换为给定的String。要将文件中的所有字符替换为“#”,但不包括特定单词(单向)-将文件的内...
  • 正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。 用到的一些特殊构造正则表达式的意义解析: ?
  • java -- 正则表达式

    2013-08-08 17:34:38
    正则表达式主要用在以下一些地方:1、搜索和替换2、验证:检查某个字符串是否符合特定的匹配模式。例如email。电话等。3、解释:解析就是从一个文件中获取有用信息的过程。有关正则表达式的内容可参考java.util....
  • 前言无论是哪一门语言,我们总会用到正则表达式来进行字符串的查找和替换Java中也不为过,我曾经写过一个网页---正则表达式在线测试。那时候,我还没有开始学习Java,不知道Java支持正则表达式,所以我的第一个...
  • 前言无论是哪一门语言,我们总会用到正则表达式来进行字符串的查找和替换Java中也不为过,我曾经写过一个网页---正则表达式在线测试。那时候,我还没有开始学习Java,不知道Java支持正则表达式,所以我的第一个...
  • 正则表达式

    2014-12-03 14:51:39
    /\s+java\s+/ //匹配字符串"java" ,并且该串前后可以有一个或多个空格. /[^"] * / //匹配零个或多个非引号字符. 正则表达式的复制字符 字符 含义 ________________________________________________________...
  • 正则表达式和Object类

    2017-04-19 20:52:37
    /*在对字符串数据进行一些复杂的匹配,查找,替换等操作时,通过正则表达式,可以方便实现字符串的复杂操作  *   */ public class Test1 { public static void main(String[] args) { // String regex="...
  • 正则表达式经典实例

    2014-07-11 14:39:05
    3.20 拆分字符串,保留正则匹配 3.21 逐行查找 第4章 合法性验证和格式化 4.1 E-mail地址的合法性验证 4.2 北美电话号码的合法性验证和格式化 4.3 国际电话号码的合法性验证 4.4 传统日期格式的合法性验证 ...
  • 前言无论是哪一门语言,我们总会用到正则表达式来进行字符串的查找和替换Java中也不为过,我曾经写过一个网页---正则表达式在线测试。那时候,我还没有开始学习Java,不知道Java支持正则表达式,所以我的第一个...
  • API的使用String类的replaceAll()方法接受两个表示正则表达式的字符串和一个替换String,并将匹配的值替换为给定的String。的java.util类(构造)接受文件,InputStream的,路径和,字符串对象,读取所有通过令牌使用...
  • 前言无论是哪一门语言,我们总会用到正则表达式来进行字符串的查找和替换Java中也不为过,我曾经写过一个网页—正则表达式在线测试。那时候,我还没有开始学习Java,不知道Java支持正则表达式,所以我的第一个方案...
  • 支持特征替换和提取,支持正则替换,支持多规则同时替换并可以行导入规则,智能规则排序功能,支持多级目录、大小写匹配、支持备份和恢复,替换速度快。 1.完全绿色安装,单独的可执行文件,操作方便 2.段落文字的...
  • 正则表达式经典实例.pdf

    热门讨论 2013-01-26 15:14:37
    3.20 拆分字符串,保留正则匹配 3.21 逐行查找 第4章 合法性验证和格式化 4.1 E-mail地址的合法性验证 4.2 北美电话号码的合法性验证和格式化 4.3 国际电话号码的合法性验证 4.4 传统日期格式的合法性验证 4.5 对...
  • 正则表达式造成栈内存溢出 2020/09/16 最近由于公司需求,需要实现这样一个功能: 从大量doc文件(大约有150w+个文件)中读取内容,剔除部分敏感信息,存入...剔除敏感信息需要使用正则表达式匹配替换成空字符串或者**
  • 主要介绍了Python删除Java源文件中全部注释的实现方法,涉及Python读取文件正则匹配字符串查找、替换等相关操作技巧,需要的朋友可以参考下

空空如也

空空如也

1 2 3 4 5 6
收藏数 107
精华内容 42
关键字:

java正则匹配文件替换字符串

java 订阅