java中regex

最近,我收到了Packt出版的Anubhava Srivastava提供的免费书籍“ Java 9 Regular Expressions” 。 这本书是一个很好的教程,它向想要学习正则表达式并从头开始的任何人介绍。 那些知道如何使用正则表达式的人可能仍然很有趣,以重申其知识并加深诸如零长度断言,反向引用之类的复杂特征。

在本文中,我将重点介绍特定于Java 9且在早期版本的JDK中不可用的正则表达式功能。 但是,数量并不多。

Java 9正则表达式模块

Java 9中的JDK分为多个模块。 可以理所当然地期望为正则表达式处理包和类提供一个新模块。 其实没有。 模块java.base是默认模块,默认情况下所有其他模块都依赖该模块,因此,导出的包的类在Java应用程序中始终可用。 此模块导出正则表达式包java.util.regex 。 这使开发过程更加简单:如果我们想在代码中使用正则表达式,则无需显式地“要求”模块。 似乎正则表达式对于Java是如此重要,以至于它包含在基本模块中。

正则表达式类

java.util.regex包含这些类

  • MatchResult
  • Matcher
  • Pattern
  • PatternSyntaxException

更改API的唯一类是Matcher

类匹配器的变化

Matcher类添加了五个新方法。 其中四个是现有方法的重载版本。 这些是:

  • appendReplacement
  • appendTail​
  • replaceAll​
  • replaceFirst​
  • results​

前四个存在于较早的版本中,并且参数的类型仅发生变化(毕竟这就是重载的意思)。

appendReplacement / Tail

对于appendReplacementappendTail ,唯一的区别是该参数还可以是StringBuilder ,而不仅是StringBuffer 。 考虑到StringBuilder是Java 1.5中引入的,就像13年前一样,没有人可以说这是一个不明智的行为。

有趣的是,API JDK的当前在线版本如何记录StringBuilder参数的appendReplacement行为。 较旧的StringBuffer变量方法显式记录了替换字符串可能包含将由相应组替换的命名引用。 StringBuilder争论的版本错过了这一点。 该文档似乎像复制/粘贴然后进行编辑。 文本将“ buffer”替换为“ builder”等,并删除记录命名参考功能的文本。

我使用Java 9 build160尝试了该功能,对于这两个方法版本,结果是相同的。 这并不奇怪,因为这两种方法的源代码是相同的,除了参数类型之外,在JDK中都是简单的复制/粘贴。

似乎可以使用

@Testpublic void testAppendReplacement() {Pattern p = Pattern.compile("cat(?<plural>z?s?)");//Pattern p = Pattern.compile("cat(z?s?)");Matcher m = p.matcher("one catz two cats in the yard");StringBuilder sb = new StringBuilder();while (m.find()) {m.appendReplacement(sb, "dog${plural}");//m.appendReplacement(sb, "dog$001");}m.appendTail(sb);String result = sb.toString();assertEquals("one dogz two dogs in the yard", result);}

注释行或每行上方的行。 但是,文档仅涉及编号的参考。

replaceAll / First

这也是一种“旧的”方法,用一些新的字符串替换匹配的组。 旧版本和新版本之间的唯一区别是替换字符串的提供方式。 在老版本的字符串被赋予作为String调用方法之前计算。 在新版本中,字符串作为Function<MatchResult,String> 。 每个匹配结果都会调用此函数,并且可以动态计算替换字符串。

知道Function类是3年前才在Java 8中引入的,因此在正则表达式中对它的新使用可能有点破绽。 或者,也许……也许我们应该将其视为一个提示,即从现在开始十年,当Fuction类已经13岁时,我们仍然会有Java 9?

让我们更深入地研究这两种方法。 (实际上只用于replaceAll因为replaceFirst相同,只不过它只替换第一个匹配的组。)当这样的使用有价值时,我尝试创建一些并非绝对复杂的示例。

第一个示例来自JDK文档:

@Testpublic void demoReplaceAllFunction() {Pattern pattern = Pattern.compile("dog");Matcher matcher = pattern.matcher("zzzdogzzzdogzzz");String result = matcher.replaceAll(mr -> mr.group().toUpperCase());assertEquals("zzzDOGzzzDOGzzz", result);}

它不太复杂,并显示了功能。 使用lambda表达式绝对足够。 我无法想象一种简单的方法将常量字符串文字“ dog”大写。 也许只写“ DOG”。 好吧,我只是在开玩笑。 但是实际上这个例子太简单了。 对于文档来说是可以的,更复杂的事情会使读者分心于所记录方法的功能。 确实:不要期望JavaDoc中的复杂示例更少。 它描述了如何使用API​​,而不是描述了为什么以这种方式创建API。

但是现在我们现在将看一些更复杂的例子。 我们要在字符串中用数字1、2、3等替换#字符。 该字符串包含编号的项目,如果我们在该字符串中插入了一个新项目,我们不想手动重新编号。 有时我们将两个项目组合在一起,在这种情况下,我们编写## ,然后只想跳过下一个#的序列号。 由于我们已经进行了单元测试,因此代码比我可以用语言更好地描述了功能:

@Testpublic void countSampleReplaceAllFunction() {AtomicInteger counter = new AtomicInteger(0);Pattern pattern = Pattern.compile("#+");Matcher matcher = pattern.matcher("# first item\n" +"# second item\n" +"## third and fourth\n" +"## item 5 and 6\n" +"# item 7");String result = matcher.replaceAll(mr -> "" + counter.addAndGet(mr.group().length()));assertEquals("1 first item\n" +"2 second item\n" +"4 third and fourth\n" +"6 item 5 and 6\n" +"7 item 7", result);}

传递给replaceAll的lambda表达式获取计数器并计算下一个值。 如果我们使用一个#那么如果我们使用两个,它将增加1,然后将其添加到计数器,依此类推。 因为lambda表达式不能在周围环境中更改变量的值(变量必须有效地为final),所以计数器不能为intInteger变量。 我们需要一个具有int值并且可以更改的对象。 AtomicInteger就是即使我们不使用它的原子功能也是如此。

下一个示例更进一步,并进行了一些数学计算。 它将字符串中的任何浮点格式的数字替换为其正弦值。 这样,由于sin(pi)甚至不接近pi,因此它可以纠正我们的句子,此处无法精确表示。 它几乎接近零:

@Testpublic void calculateSampleReplaceAllFunction() {Pattern pattern = Pattern.compile("\\d+(?:\\.\\d+)?(?:[Ee][+-]?\\d{1,2})?");Matcher matcher = pattern.matcher("The sin(pi) is 3.1415926");String result = matcher.replaceAll(mr -> "" + (Math.sin(Double.parseDouble(mr.group()))));assertEquals("The sin(pi) is 5.3589793170057245E-8", result);}

我们还将对此计算进行一些操作,以演示列表中的最后一个方法,它是Matcher类中的一个全新方法。

流结果()

新方法results()返回匹配结果流。 更精确地说,它返回MatchResult对象的Stream 。 在下面的示例中,我们使用它从字符串中收集任何浮点格式的数字,并以逗号分隔打印其正弦值:

@Testpublic void resultsTest() {Pattern pattern = Pattern.compile("\\d+(?:\\.\\d+)?(?:[Ee][+-]?\\d{1,2})?");Matcher matcher = pattern.matcher("Pi is around 3.1415926 and not 3.2 even in Indiana");String result = String.join(",",matcher.results().map(mr -> "" + (Math.sin(Double.parseDouble(mr.group())))).collect(Collectors.toList()));assertEquals("5.3589793170057245E-8,-0.058374143427580086", result);}

摘要

Java 9 JDK中引入的新正则表达式方法与现有的方法没有本质上的区别。 它们整洁方便,在某些情况下可以简化编程。 没有早期版本中不会引入的任何内容。 这只是Java缓慢而深思熟虑地对JDK进行此类更改的方式。 毕竟,这就是为什么我们喜欢Java,不是吗?

您可以从以下要点找到并下载IDE中的整个代码副本粘贴

翻译自: https://www.javacodegeeks.com/2017/08/new-regex-features-java-9.html

java中regex

java中regex_Java 9中的新Regex功能相关推荐

  1. Java 9中的新Regex功能

    最近,我收到了Packt出版的Anubhava Srivastava提供的免费书籍" Java 9 Regular Expressions" . 这本书是一个很好的教程,它向任何想 ...

  2. Java部分A+B正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。现给定A、DA

    题目描述: 正整数A的"DA(为1位整数)部分"定义为由A中所有DA组成的新整数PA.例如:给定A = 3862767,DA = 6,则A的"6部分"PA是66 ...

  3. Java 14 中令人期待的五大新特性!

    随着新的 Java 发布生命周期的到来,新版本预计将于 2020 年 3 月发布,本文将对其中的 5 个主要特性作些概述. 作者 | Sylvain Saurel 译者 | 苏本如,责编 | 郭芮 出 ...

  4. JAVA实现在面板中添加图表_java-如何在不制作新图表的情况下将jzy3d图表添加到JFrame?...

    以下代码用于在JFrame中制作jzy3d图表: public class SurfaceViewerFrame extends IconFrame { public SurfaceViewerFra ...

  5. 【Java 8 新特性】Java Comparator 在 SortedMap 中使用 | TreeMap 和 ConcurrentSkipListMap 排序

    Java Comparator 在 SortedMap 中使用 | TreeMap 和 ConcurrentSkipListMap 排序 在 TreeMap 中使用 在 ConcurrentSkipL ...

  6. java 判断 中文字符_java中判断字符串中是否有中文字符

    package com.meritit.test; public class TestChart { public static void main(String[] args) throws Exc ...

  7. word录入表单数据 java 导入系统,java导入excel | 怎么把excel中的数据批量导入到word中的表格中...

    用javascript怎么实现把excel中的数据批量导入到数据库表中 这个js不能直接实现吧 我们程序用到 先读取excel内容转换成数组 然后放到页面上 再提交表单 储存 MySql如何批量添加数 ...

  8. java中JFrame类中函数addWindowListener(new WindowAdapter)

    在java编写的过程中常常遇到样的一段代码 frame.addWindowListener(new WindowAdapter() {@Override public void windowClosi ...

  9. java string与integer_Java中Integer和String浅谈

    http://qxzxcjq-126-com.iteye.com/blog/883283 Java中的基本数据类型有八种:int.char.boolean.byte.long.double.float ...

最新文章

  1. 使用深度学习检测DGA(域名生成算法)——LSTM的输入数据本质上还是词袋模型...
  2. SIMD指令集——一条指令操作多个数,SSE,AVX都是,例如:乘累加,Shuffle等
  3. idea启动webservice_idea使用springboot的webservice基于cxf
  4. SwitchyOmega 配置
  5. XorPay.com 支付平台介绍【支持个人申请】
  6. 谁今天收到鸿蒙系统推送,鸿蒙系统正式推送,只有部分高端机才能收到
  7. 关于Unity实现AR功能(五)摄像头转换与闪光灯开关控制
  8. 说唱计算机网红,首档喊麦节目太奇葩,蹭了说唱热度,还请了被封杀网红当导师...
  9. 数列求和 java_[代码展示]数列求和
  10. layui中折叠面板的使用
  11. 下载sqlserver2012 试用_大肥虫助手app下载-大肥虫助手最新版本下载v7.0.4
  12. idea springboot学习笔记
  13. 让Ipad买前爱奇艺买后生产力——浏览器编程之Projector运行Idea(超详细)
  14. 手机(摩托罗拉、索爱、西门子、LG)大部分机型的cpu型号
  15. tasklist、taskkill、taskmgr
  16. Dubbo-接口数据序列化Serialization
  17. 游戏定制开发自建团队好吗?
  18. 自行车平衡java小游戏_自行车水上平衡赛
  19. 公众号bmob_newgd.js
  20. 电脑文件里哪里能用计算机,如何搜索电脑文件和文件夹

热门文章

  1. P5044-[IOI2018] meetings 会议【dp,笛卡尔树,线段树二分】
  2. P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】
  3. jzoj3512-游戏节目【树状数组,双向dfs】
  4. codeforces1497 E. Square-free division(数学+dp)
  5. codeforces 932D Tree 倍增法+二分搜索
  6. I - Trade Gym - 100212I 网络流
  7. Spark入门(八)之WordCount
  8. MyEclipse生成Javadoc帮助文档
  9. Intellij Idea乱码解决方案都在这里了
  10. Ajax基本案例详解之$.getjson的实现