一、前语

不着急讲述Regex,咱们先看一个需求,统计某个字符或字符串在整个字符串中呈现的次数,举例,字符串如下:

今日是2023年6月29日,北京,气候晴,与昨日不同的是,今日分外的热,也不知道明日会怎么样,是晴天仍是阴天呢,详细得到明日才干知道了。

请统计“天”字呈现的次数。

完成上边的功用,我相信咱们,有很多种办法,下面也举例几种:

1、循环遍历

这是最常见,也是首先能想到的。

 val content = "今日是2023年6月29日,北京,气候晴,与昨日不同的是,今日分外的热,也不知道明日会怎么样,是晴天仍是阴天呢,详细得到明日才干知道了。"
 var count=0
        //遍历
 content.forEach {
     if ('天' == it) {
           count++//次数累加
        }
 }
 print(count)

打印成果

8

2、Kotlin中count操作符

 val content = "今日是2023年6月29日,北京,气候晴,与昨日不同的是,今日分外的热,也不知道明日会怎么样,是晴天仍是阴天呢,详细得到明日才干知道了。"
 val count=content.count { ch -> ch == '天' }
 print(count)

打印成果

8

3、Kotlin中的filter操作符

 val content = "今日是2023年6月29日,北京,气候晴,与昨日不同的是,今日分外的热,也不知道明日会怎么样,是晴天仍是阴天呢,详细得到明日才干知道了。"
 val filterContent=content.filter { ch -> ch == '天' }
 print(filterContent.length)

打印成果

8

4、运用Java中的正则

val content = "今日是2023年6月29日,北京,气候晴,与昨日不同的是,今日分外的热,也不知道明日会怎么样,是晴天仍是阴天呢,详细得到明日才干知道了。"
        val pattern = Pattern.compile("天")
        val matcher = pattern.matcher(content)
        var count = 0
        while (matcher.find()) {
            count++
        }
print(count)

打印成果

8

5、运用Regex方针

val content = "今日是2023年6月29日,北京,气候晴,与昨日不同的是,今日分外的热,也不知道明日会怎么样,是晴天仍是阴天呢,详细得到明日才干知道了。"
val matchResult = Regex("天").findAll(content)
print(matchResult.count())

当然了还有很多的完成办法,咱们暂时举这五种,看到第五种的Regex方针完成办法,有的铁子就问了,我一点点没有发现Regex到底有什么可取之处啊,简略吗?与Kotlin的操作符比较,几乎便是小巫见大巫,毫无长处可言,别慌啊铁子,假如仅仅简略的文本寻觅,Regex肯定没有优势,毕竟,这仅仅它的一个引子,冰山一角的功用,咱们慢慢拉开序幕~

二、Regex办法罗列

经过以上的前语,咱们大致知道了,本来Regex也能够完成查找的功用,无形傍边,又多了一种挑选办法,除此之外,它还有那些功用呢?

结构函数

咱们先看一下根本的结构函数

办法 参数类型 概述
Regex(pattern:String) String 要匹配的正则表达式形式。
Regex(pattern:String,option:RegexOption) String,RegexOption 依据指定的形式字符串和指定的单个选项创立正则表达式。
Regex(pattern:String,options:Set) String,Set 依据指定的形式字符串和指定的选项集创立正则表达式

关于一个参数的结构,没什么好说的,便是一个正则表达式,这也是咱们最常用的,至于后边两个,相对运用的较少,不过咱们仍是简略的介绍一下:

RegexOption是一个枚举类型,详细类型如下:

参数 概述
IGNORE_CASE 启用不区别大小写的匹配。大小写比较支持Unicode
MULTILINE 启用多行形式。在多行形式中,表达式^和$分别在输入序列的行终止符或末尾之后或之前匹配。
LITERAL 启用形式的文字剖析。输入序列中的元字符或转义序列将不会被赋予特殊含义。
UNIX_LINES 启用Unix行形式。在这种形式下,只要’\n’被识别为行终止符。
COMMENTS 答应在形式中运用空格和注释。
DOT_MATCHES_ALL 启用表达式时的形式。匹配任何字符,包括行终止符。
CANON_EQ 经过标准分化完成等价。

咱们能够依据不同的情况,挑选对应的参数即可,至于Set,无非便是多个RegexOption。

常见办法

了解完根本的结构,咱们再来看下常用的办法:

办法 参数类型 概述
find(input:CharSequence,startIndex:Int=0) CharSequence,Int 寻觅字符串中第一个匹配的MatchResult方针,默认从索引0开端。
findAll(input:CharSequence,startIndex:Int=0) CharSequence,Int 字符串中所有匹配的MatchResult序列,默认从索引0开端。
containsMatchIn(input:CharSequence) CharSequence 假如包括输入的字符就返回true。
replace(input:CharSequence,replacement:String) CharSequence,String 和String的replace相似,第一个是输入的方针字符,第二个是替换字符。
replaceFirst(input:CharSequence,replacement:String) CharSequence,String 替换第一个查找到的字符
matches(input:CharSequence) CharSequence 输入字符序列是否与正则表达式匹配
matchEntire(input:CharSequence) CharSequence 用于匹配形式中的完整输入字符

三、Regex常见办法运用举例

在上篇文章《Android:这个需求搞懵了,产品说要完成富文本回显展示》中,不知道咱们是否还有形象,关于富文本的截取,咱们就采用了Regex,简简略单的就完成了富文本的内容获取,当然了也简略的介绍了部分的办法。下面,咱们针对第二项中的各个办法,简略做个运用事例。

1、find

find,用于寻觅第一次呈现的成果,比方咱们要寻觅某个字符串中第一次呈现的数字,如下举例:

  val content = "有这样一串数字2345,还有6789,以及012,咱们怎么只获取数字2345呢"
  val regex = Regex("\d+")
  val matchResult = regex.find(content)
  print(matchResult?.value)

打印成果

2345

2、findAll

findAll,望文生义,便是寻觅所有的成果,仍是上面那个事例,咱们改成findAll

 val content = "有这样一串数字2345,还有6789,以及012,咱们怎么只获取数字2345呢"
 val regex = Regex("\d+")
 val matchResult = regex.findAll(content)
 matchResult.forEach {
      println(it.value)
 }

打印成果

2345
6789
012
2345

还有一个典型的事例,便是富文本标签的截取,这个在上篇文章举例过了,咱们能够看上篇文章。

3、containsMatchIn

用于判别是否包括某个字符,和String的运用办法相似:

 val content = "二流小码农"
 val regex = Regex("农")
 val regex2 = Regex("中")
 val isContains = regex.containsMatchIn(content)
 val isContains2 = regex2.containsMatchIn(content)
 println(isContains)
 println(isContains2)

打印成果

true
false

4、replace

用于替换字符串中的相关内容:

 val content = "二流小码农"
 val regex = Regex("二")
 val replaceContent=regex.replace(content,"一")
 println(replaceContent)

打印成果

一流小码农

5、replaceFirst

用于替换字符串中第一次相符合的内容:

val content = "有这样一串数字2345,还有6789,以及012,咱们怎么只获取数字2345呢"
val regex = Regex("\d+")
//把第一次呈现的数字替换为字母abcd
val replaceContent=regex.replaceFirst(content,"abcd")
println(replaceContent)

打印成果

有这样一串数字abcd,还有6789,以及012,咱们怎么只获取数字2345呢

6、matches

用于输入的字符和方针内容是否匹配,比方用于邮箱的验证,手机号的验证等等情况:

//邮箱验证
val content = "11@qq.com"
val content2 = "11@qq"
val regex = Regex("[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+")
val matches=regex.matches(content)
val matches2=regex.matches(content2)
println(matches)
println(matches2)

打印成果

true
false

7、matchEntire

用于匹配形式中的完整输入字符。

 //匹配数字
 val regex = Regex("\d+")
 val matchResult=regex.matchEntire("二流小码农")
 val matchResult2=regex.matchEntire("二流小码农666")
 val matchResult3=regex.matchEntire("123456")
 println(matchResult?.value)
 println(matchResult2?.value)
 println(matchResult3?.value)

打印成果

null
null
123456

四、总结

Regex相关于Java的Api来说,运用起来更加的简略,假如咱们在非正则的功用运用时,比方寻觅,替换,是否包括等等,完全能够运用字符串自带的功用即可,假如说要完成一些较为杂乱的,比方邮箱的验证,手机号的验证等等,那么Regex肯定是你的首选。