Scala 正则详解以及相关技巧总结
- 这篇博客的代码来源自Scala的Regex.scala文件,这里就不带大家看源码了,但是例子都是源码中的东西(可能稍微做了点修改)
文章目录
- Scala 正则详解以及相关技巧总结
-
-
-
- 1.关于正则匹配中的group
- 2.抽取已匹配的正则表达式中的部分内容(模式匹配表达式要写全)
- 3.测试正则表达式是否被匹配
- 4.抽取已匹配的正则表达式中的部分内容(模式匹配表达式不用写全)
- 5.在给定字符串中查找指定模式的正则是否存在其中
- 6.findFirstIn方法:匹配一个字符串中符合正则表达式的第一个字符串:
- 7.匹配一个字符串中符合正则表达式的字符串中第一个group的满足正则匹配的值
- 8.匹配一个字符串中符合正则表达式的字符串第一个group的所有满足值
- 9.findAllIn:方法返回一个特殊的迭代器对象能够做最后的match查询
- 10.findAllIn()方法不会进行重叠匹配
- 11.文本替换可以无条件执行,也可以作为当前匹配的函数执行:
- 12.模式匹配中获取整个group的值
- 13.scala的字符的匹配
- 14.字符匹配当中,如果正则表达式中有多个group只返回一个值
- 15.匹配字符串中的子字符串
-
-
group
?大致的意思就是如果一个正则表达式中有部分被括号包裹了例如(\d+)年
,那么这个正则表达式中就存在一个group
,(\d+)年(\d+)月
这样的话,里面就存在两个group
。好的,下面我要开始介绍一下其它的操作了,走起来- 1.
group
的表达式的基本用法
如果是没有group
的正则表达式的话例如:
文章图片
那么这样是可以调用的,没有问题
得到的结果就是显示一个true
:
文章图片
注意:如果正则表达式中存在一个group
的话
比如:
文章图片
结果:
文章图片
结果为true
,没有问题
现在将代码修改成如下形式:
文章图片
上面就是将match
中的p2(_*)
修改成了p2()
,这里的话,程序执行,编译不报错,但是p2Matches
会得到false
的结果。( 我的猜测就是正则表达式如果带有group
的话,那么在match
匹配中针对这个正则表达式,不传入的参数的话,就匹配不上,可能是在匹配的过程中会将这个字符串拆分成一个一个字符序列,然后将其与正则表达式相匹配)
- 【scala|Scala:正则表达式详解】2.正则表达式中的group起别名
创建一个新的带有group
的正则匹配的表达式,可以为每个group
起一个别名,代码示例如下:
文章图片
结果如下:
文章图片
上图打印出了group
的名为year
的对应的字符串表达式。
- 3.含有
group
的match
匹配中的case
中含有带变量名的正则表达式
在带有group
的mach
当中的正则表达式的括号里面可以给定一个变量的名,这样在进行模式匹配的过程中,如果有满足这个正则表达式的group
的字符串里面。这个变量名就指代着这个字符串,然后就可以调用其中的一些方法了。代码案例如下:
文章图片
输出的结果如下:
文章图片
结果正如上所述,可以在模式匹配中抽取group
中正则匹配出来的部分数据,做其它操作。
文章图片
结果显示:
文章图片
注意: 正则表达式中对应的提取位置需要有括号包裹,没有使用括号包裹的话,数据是无法提取出来的。
3.测试正则表达式是否被匹配
文章图片
结果:
文章图片
这种做法就是单纯的检验正则表达式能否被匹配
4.抽取已匹配的正则表达式中的部分内容(模式匹配表达式不用写全)
文章图片
结果:
文章图片
注意:
此处之所以可以不用写全模式匹配中的表达式,是因为在
dataRegex
中添加了一个新的参数_*
,因为这个参数的存在,可以检验整个正则表达式能否被匹配上带匹配数据。然后再从这个正则匹配表达式中抽取想要的数据。另外应该注意到的一个点是:
case dateRegex(year,_*)
中里面的参数名字虽然叫做year
,然而并不是说会有目的性的提取year
这个变量,而应该总是提取第一个变量。5.在给定字符串中查找指定模式的正则是否存在其中
文章图片
结果:
文章图片
注意
这里面的
case embeddedDate()
中的三个参数要满足dataRegex
中括号里面的三个表达式,然后在待预测的字符串"Date: 2004-01-20 17:25:18 GMT (10 years, 28 weeks, 5 days, 17 hours and 51 minutes ago)"
中必须要存在,才能匹配上。6.findFirstIn方法:匹配一个字符串中符合正则表达式的第一个字符串: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191229170404876.png
文章图片
结果:
文章图片
这段代码的功能是返回结果字符串第一个满足正则表达式匹配的字符串。
7.匹配一个字符串中符合正则表达式的字符串中第一个group的满足正则匹配的值 (这个标题是我自己写的,如果有更好的描述请在下面评论中给点建议啊,语文不是特别优秀,见谅)
文章图片
结果:
文章图片
解释:
在
datas
字符串中找到了满足正则表达式的第一个子字符串2004-01-20
,然后从这个字符串中获取匹配正则表达式的第一个部分的字符串2004
即:2004
满足正则表达式(\d\d\d\d)
8.匹配一个字符串中符合正则表达式的字符串第一个group的所有满足值 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191229172951798.png
文章图片
结果:
文章图片
这个代码与上面的代码不同的地方就是
findFirstMatch
修改成findAllMatch
这样的话就可以获取所有满足正则匹配表达式的字符串,并将他们组成一个集合,然后在这个集合当中。将所有的满足正则表达式中第一部分的内容字符串提取出来组成一个集合,并将它们返回。9.findAllIn:方法返回一个特殊的迭代器对象能够做最后的match查询
文章图片
结果:
文章图片
解释:
也就是指调用了
findAllIn
函数之后,返回的迭代器的类型很特殊(在途中可以看到一个Regex.MatchIterator)的迭代器类型。接着利用这个迭代器进行一个过滤操作(过滤出满足正则匹配表达式中的第一部分的值小于1960的结果)10.findAllIn()方法不会进行重叠匹配
文章图片
结果:
文章图片
解释:
可以看到正则表达式
num
是(\d+)
这个意思是:匹配至少一个数字,程序的运行结果是:List(123)
也就是说程序不会匹配得到类似List("123","23","3")
这样的结果。11.文本替换可以无条件执行,也可以作为当前匹配的函数执行: 原文:Text replacement can be performed unconditionally or as a function of the current match:
文章图片
结果:
文章图片
例如这个操作,调用的是
Regex
实例里面的replaceAllIn()
的方法,而一般我们平常写的都是String
调用replaceAll()
方法的方式是不同的(String
的replaceAll()
的方法 str.replace("regex string","xxx str")
注意: 如果第二个参数是函数的话,那么作用又不一样了,请听我bb,例子如下:
文章图片
结果:
文章图片
这里的执行细节如下:
1.第一第二行都是定义变量,没啥好说的。
2.第三行是获取一个本地月份(1月~12月)的数组。
里面的内容如下:
文章图片
3.第四行则是,调用
Regex
类里面的repalceAll
的方法了,先找到字符串变量dates
里面符合,正则表达式date
的一个个字符串("2004-01-20","1958-09-05",2010-10-06","2011-07-15")
,然后输入到match
模式匹配中(这里与之前不一样,上面的一个小节中,第二个参数传入的是一个正则表达式字符串,当前的第二个参数中传入的是一个模式匹配的表达式),抽取满足正则表达式的各个匹配部分的字符串,然后将它们排版打印输出。模式匹配和正则表达式的匹配相比,创建时不重新应用正则表达式。在这个表达式
reformatted
(就是上面那张图里的变量),每个日期只匹配一次,但是它们可能是根据匹配的模式,应用一个正则表达式或者一个匹配模式产生结果。就比如下面这个例子(上面的那个例子中,
match
里面模式匹配的表达式,接下来的例子中match
就是正则的表达式)文章图片
结果:
文章图片
对于这个结果,没啥好说的, 应该可以看得懂。
12.模式匹配中获取整个group的值 在含有
match
的模式匹配中获取含有整个group的值,代码示例如下:文章图片
结果为:
文章图片
这个源码中的例子,我的理解是:关键点在于
p4(all @ _*)
这个地方,我对这个_*
理解是和只上文所提到的一样,将匹配的字符串转化成字符序列,然后传入到p4()
中。这个@
符号的作用是:如果,这个正则表达式中的group
被匹配上了,那么就将值赋于@
之前的变量。最后得到的变量all
是一个集合。调用mkstring
方法转换成一个字符串,然后整个match
匹配将值返回~13.scala的字符的匹配 scala对字符的匹配,代码示例如下:
文章图片
在上图中正则表达式
(\p{Lower})
是一个带有group
的表达式(下面有红色的下划线就忽略掉吧,是idea
的显示问题),所以在模式匹配当中,case
后面的表达式里面都需要传入参数。而这一行case r() => true
中没有传入参数,所以这个会在编译的时候报错scala.MatchError:c (of class java.lang.Character)
的错误,如下所示:文章图片
注意:上面的代码将
cat(0) match { case r() => true}
注释掉就好了14.字符匹配当中,如果正则表达式中有多个group只返回一个值 如下所示:
文章图片
控制台上会打印一个true:
文章图片
如果
match
的模式匹配中写成如下的形式:文章图片
结果显示为:
文章图片
就说明没有匹配上。
15.匹配字符串中的子字符串 有的时候我们需要匹配给定的一个字符串中的子字符串。
比如我们要判断一个字符串:
abcd1234
中是否含有数字,我们可以这样实现:文章图片
结果为true 比较简单
以上内容就是我从
Scala
的Regex.scala
文件中总结出来的,希望能对看到这篇文章的小伙伴们有一点点的帮助,如果你发现了我的文章里面有哪些地方写得不够好,请在评论下方留言。谢谢!推荐阅读
- 字符串|深入正则表达式(3):正则表达式工作引擎流程分析与原理释义
- 正则表达式|c#正则表达式——匹配不同类型的一个字符
- 正则表达式|一看就懂(正则表达式)
- 神经网络|目标检测算法YOLOv4详解
- 深度学习与神经网络|计算机视觉之卷积神经网络
- 区块链|教程丨三分钟教你制作专属NFT智能合约
- 编程语言|宁愿“大小周”、每天只写 200 行代码、月薪 8k-17k 人群再涨!揭晓中国开发者真实现状...
- C语言的常量|C语言的常量,字符串,转义字符,注释你都了解吗
- 大数据|Docker员工自述(我们为什么“输”给了K8s())