正则表达式——Java程序员懂你

正则表达式

关键字:正则表达式,Pattern,Matcher,字符串方法,split,replace

前文书立下了一个flag,这里要把它完成,就是正则表达式,它是一个工具,是很早就存在于标准Unix工具集之中的,例如sed和awk。然而不经常使用Unix系统的程序员们依然能够在JavaScript,java,python,perl等等地方看到它,每当我们看到手指纷飞的他人写着精妙的一小撮正则就干了我们好几篇的校验代码的时候,心里默默升起一股羡慕之情,同时只能赶紧把这一小撮正则保存下来,下次好修修补补继续用,那么,我们能否读懂正则表达式呢,不再把它们作为天书看待。

Java程序员普遍对与正则表达式并不算深入,因为我们有String以及StringBuilder,我们引以为傲的强大的java的字符串的处理在正则表达式的面前只能是小垃。

正则表达式是一种强大灵活的文本处理工具,通过它能够解决各种字符串处理相关的问题:匹配、选择、编辑以及验证,Java程序员们,扔掉split(),replace()以及subString()吧,每次通过他们的组合变来变去只为了实现一个我们不到一首诗的时间的需求,简直对计算机和对我们本人来讲都是一种消耗。

一、热身

首先介绍几个最基础的正则表达式热热身。

  • 正则表达式使用反斜杠\来转义特殊字符,java中使用两个反斜杠\\
  • ?: 一个或者没有
  • +: 一个或者多个
  • \d: 数字
  • (): 用括号分组,整体相当于一个单独的字符
  • |: 代表或者,一般与括号分组一起使用

下面看具体代码,

测试方案

这里的测试方案是采用的之前io中文件名过滤器的那段代码。首先我们定义一个字符串数组作为源数据。

String[] data = { "a.txt", "+", "12345", "8", "-2", "-2123", "+010" };

这些字符串中基本包含了我们以下要练手的内容。接着,定义一个简单的获取数字的正则。

String regExp = "\\d";// 一位数的正整数字符【只匹配一个】

然后下面使用这个正则的方式为:

for (String s : data) {
    if (Pattern.matches(regExp, s))
        logger.info(s);
}

意思为遍历字符串数组,如果匹配了该正则表达式,则打印出来(这里只做一个测试方案,具体Pattern以及Matcher在下面会有详细介绍)。这段代码的输出结果为:

09:21:02[testRegExp]: 8

开始测试

上面的测试方案中我们写入的正则表达式是“\\d”,只匹配一位正整数字符。下面开始正式热身测试。

regExp = "\\d+";// 正数数字【加号+代表一个或者多个】
09:33:48[testRegExp]: 12345
09:33:48[testRegExp]: 8
regExp = "-?\\d+";// 数字(包括正数和负数)
09:34:27[testRegExp]: 12345
09:34:27[testRegExp]: 8
09:34:27[testRegExp]: -2
09:34:27[testRegExp]: -2123
regExp = "-\\d+";// 所有负数【只匹配以一个字符‘-’开头的】
09:34:49[testRegExp]: -2
09:34:49[testRegExp]: -2123
regExp = "-\\d";// 只有一位数的负数【只匹配以一个字符‘-’开头的,同时只有一位整数的字符串】
09:35:06[testRegExp]: -2

从上面这四段正则可以总结出来,假设有一个字符a,我们匹配它各种情况的正则表达式的方式为:

a?(一个或者没有) -> a(只有一个) -> a+(一个或者多个)

regExp = "\\+";// 内容为加号的字符串
09:37:21[testRegExp]: + 
regExp = "\\+\\d+";// 以加号开头接整数的字符串
09:37:59[testRegExp]: +010

这两段的意思是我们要匹配加号,但加号本身又是正则表达式的一部分运算符,所以要加\\来将其转义为普通字符。

regExp = "(\\+|-)\\d+";// 以一个加号或者一个负号开头的数字
09:39:29[testRegExp]: -2
09:39:29[testRegExp]: -2123
09:39:29[testRegExp]: +010
regExp = "(\\+|-)?\\d+";// 以一个加号或者一个负号开头或者没有符号的数字
09:39:47[testRegExp]: 12345
09:39:47[testRegExp]: 8
09:39:47[testRegExp]: -2
09:39:47[testRegExp]: -2123
09:39:47[testRegExp]: +010

这两段我们使用了括号用来表示一个分组,整个括号内容相当于一个单独的字符。

String方法中的正则表达式

上面提到过java字符串中的split,replace等方法,他们是支持正则表达式的,所以不要只用他们的字符串简单操作,划分替换的部分,还可以应用一下正则表达式,正则表达式给了我们编程上一个模糊查询的作用,对比起来直接使用字符串本身作为搜索参数,一个正则表达式可以代表的内容更加丰富。

  • split方法
String regex = " ";// 按空格来划分字符串
regex = "\\W+";// 正则选择出非单词字符,split过滤一遍以后剩下纯单词,删除其他符号
regex = "g\\W+";// 字母n后面跟着非单词字符,也就是‘n后面有空格字符’,split以后就去掉了n和这个空格
String preface = "I wish I had this book when I started programming... I recommend this book to every student as well as beginner and intermediate Java programmer.";
String[] a = preface.split(regex);
logger.info(a.length + " " + Arrays.toString(a));
11:03:17[testSplit]: 2 [I wish I had this book when I started programmin, I recommend this book to every student as well as beginner and intermediate Java programmer.]
  • replace方法
logger.info(preface.replaceFirst("p\\w+", "heyhey"));// 将第一个p打头的单词改为heyhey
logger.info(preface.replaceAll("p\\w+", "heyhey"));// 将全部p打头的单词改为heyhey
11:03:17[testSplit]: I wish I had this book when I started heyhey... I recommend this book to every student as well as beginner and intermediate Java programmer.
11:03:17[testSplit]: I wish I had this book when I started heyhey... I recommend this book to every student as well as beginner and intermediate Java heyhey.

具体解释请直接看代码中的注释。

二、java.util.regex

前面的正则表达式都是一个字符串对象,然而java支持了专门的更加强大的正则表达式相关的类。下面来介绍如何在java中创建一个正则表达式,主要是在java.util.regex中的Pattern类和Matcher类。

Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
logger.info(b);
输出:true

如果不涉及模式重用、匹配器重用,可以改为

logger.info(Pattern.matches("a*b", "aaaab"));
11:22:59[testRegex]: true

上面介绍过?,无符号和+,分别代表一个或没有,一个,一个或多个,那么有没有一个符号可以覆盖它们所有情况,代表没有或有,一个或多个呢?

  • *: 含有一个或多个该字符,或者不含有该字符

而且一般正则表达式是小写字母代表本身意思,它的大写代表相反的意思,例如上面提到的,

  • \w: 词字符,大小写字母加数字
  • \W: 非词字符
  • ^: 非

所以\W也可以表示为[^\w],同样的,

  • \d: 匹配数字[0-9]
  • \D: 非数字[^0-9]
  • []: 方括号,表示其中的任意字符,相当于括号加|的分组
  • \s: 空白符(空格、tab、换行、换页或回车)
  • \S: 非空白符[^\s]

接着,再说几种方括号内部的情况,

  • [abc]: 包含abc任意字符的单个字符(注意只有一个字符)
Pattern p = Pattern.compile("[abc]");
logger.info(p.matcher("abc").matches());
logger.info(p.matcher("b").matches());
logger.info(p.matcher("ab").matches());
logger.info(p.matcher("c").matches());
14:15:57[testRegex]: false
14:15:57[testRegex]: true
14:15:57[testRegex]: false
14:15:57[testRegex]: true

[abc]与(a|b|c)的效果是相同的。

  • [a-zA-Z]: 同样是单个字符,字符范围是大小写字母。

方括号如果不加?,*或者+,效果与无符号的单个字符一样,代表仅匹配一个字符。

  • [abc[hij]]: 同样是匹配单个字符,范围是abchij,并集。
  • [a-z&&[hcj]]: 取的是交集,hcj在a-z的范围内,所以最终意思为匹配一个字符,字符范围在hcj任意一个。

数量的设定

正则表达式可以约定字符出现的次数,上面的?,*,+都已经提到了,那么具体的量词如何设置呢?

Pattern p = Pattern.compile("[a-z]{3}");
logger.info(p.matcher("abc234").matches());
logger.info(p.matcher("ccc").matches());
logger.info(p.matcher("ab").matches());
logger.info(p.matcher("c").matches());
15:12:49[testRegex]: false
15:12:49[testRegex]: true
15:12:49[testRegex]: false
15:12:49[testRegex]: false

总结

本文介绍的正则表达式内容比较入门,但是对于java程序员处理常见问题已经够用,尤其是读懂已有代码,修修补补的能力应该是有的。

时间: 2024-10-09 17:47:19

正则表达式——Java程序员懂你的相关文章

PHP笔记——java程序员看懂PHP程序

PHP笔记——java程序员看懂PHP程序 php是一种服务器端脚本语言,类型松散的语言. <?php   ?>       xml风格 <script language=”php”></script>   脚本风格 <?       ?>    简短风格 <%              %>    ASP风格 以;结尾: 注释: a)         // b)         # c)         /*     */ 变量是存储数据的容器

当世界上只剩下一个Java程序员

公元2050年,世界上只剩下了一个Java程序员. 你可能要问了,别的人都去哪儿了?原因很简单, Java没落了. 大约在2030年左右,出现了一个叫做X的语言,它既能做系统级开发(操作系统.数据库.编译器),也能做服务器端的开发,手机端,Web端都不在话下. 更为重要的是,这个新的编程语言和人类的自然语言很接近,无论大人小孩,稍微一学,很快就可以来编程.于是排名前100的语言统统消失了, 程序员们都失业了. Java也不例外,这个昔日的霸主在留下了一堆庞大而复杂的系统以后就不见了. Java程

[转] Java程序员学C#基本语法两个小时搞定(对比学习)

Java程序员学C#基本语法两个小时搞定(对比学习) 对于学习一门新的语言,关键是学习新语言和以前掌握的语言的区别,但是也不要让以前语言的东西,固定了自己的思维模式,多看一下新的语言的编程思想. 1.引包 using System;java用import2.构造函数和java语法相同3.析构函数  变量和类的对象都有生命周期,生命周期结束,这些变量和对象就要被撤销.  类的对象被撤销时,将自动调用析构函数.一些善后工作可放在析构函数中完成.  析构函数的名字为~类名,无返回类型,也无参数.Per

一个java程序员的真实经历

半路出家的老java程序员的一点感悟 我是一个老java程序员,现在基本告别编码时代了,当然我现在还在写代码,不是为了老板写了,是自己在创业.回想起这么多年的人生路,作为一名老程序员感慨颇多,尤其是作为一名半路出家的程序员,其中的滋味更是感慨万分.下面我就自己说说我的经历,也许会给未来码农一点启发. 首先讲讲我是怎么成为一个程序员的,这个还真要说说中国的教育.我们国家的这种应试教育一直受到很多人的诟病,有的指责扼杀了学生的创造力,有的指责培养出来的学生就像火腿厂生产的香肠,都是一个味毫无特点而言

JAVA程序员必看的15本书-JAVA自学书籍推荐

作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水平的Java程序员们.此外,大家可以加入457036818交流群,互相分享一下关于JAVA方面的知识.一.Java编程入门类 对于没有Java编程经验的程序员要入门,随便读什么入门书籍都一样,这个阶段需要你快速的掌握Java基础语法和基本用法,宗旨就是"囫囵吞枣不求甚解",先对Java熟悉

【转】你离顶尖 Java 程序员,只差这11本书的距离

个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 "看完书之后再次提升自我的最好途径是看一些相关的好博文",我个人认为这是学习的第二步,因为一本书往往有好几百页,好的博文是自己看书学习之后的一些总结和提炼,对于梳理学习的内容很有好处,当然这里不是说自己的学习方法,就不再扯下去了. 很多程序员们往往有看书的冲动,但不知道看哪些书,下面我就给各位Java程序猿们推荐一些好书(每本书

分享下多年积累的对JAVA程序员成长之路的总结

http://blog.csdn.net/zhongzelin/article/details/8643269我也搞了几年JAVA了,由于一向懒惰,没有成为大牛,只是一普通程序猿,不爱玩社交网站,不爱玩微博,唯独喜欢百度贴吧,潜水很久了,手痒来给新人分享下从新手成长为老鸟的已见,也刷刷存在感,应该不比曝照差吧. 首先初识语法的阶段,必须要学会怎么操作对象,操作if和for,操作list set map,然后是线程.IO和jdbc什么的,其余的,若是一时不理解,可以后边需要时再学.这阶段完了,你可

java程序员,英语那点事

本文选自<Java程序员,上班那点事儿>有时候如果应聘到了一个有外资背景的公司或者这个公司的很多人都有海外或外资工作背景时,你 也许还会用到一些日常工作交流时候的词汇.        比如我们看一下某主管开会时的发言:小王,请你尽快“Push”一下这件事,按照前期咱 们定下来的“Plan”来“follow”这个“case”,每一个“Milestone”都要“Share”出来,你负 责的这块工作要充分的“Open”,明天最好和客户做一个“Conference”能够“Face to face”的

CSDN日报20170320——《Java 程序员的面试经历和题库》

[程序人生]Java 程序员的面试经历和题库 作者:nuaazhaofeng 最近打算换城市了,受不了北京的雾霾了,所以准备逃离啦.所以一直在面试中,整理了下最近遇到的一些面试题,供大家参考.其中会包含一些面试的小经验,如果您是面霸,希望能给予指导.自己不是大牛,如果您是大牛,也可以忽略之.我面试的岗位是Java后端开发工程师. [Python]7行Python代码的人脸识别 作者:半吊子全栈工匠 随着去年alphago 的震撼表现,AI 再次成为科技公司的宠儿.AI涉及的领域众多,图像识别中的