前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据之脚踏实地学17--Scala字符串的清洗

大数据之脚踏实地学17--Scala字符串的清洗

作者头像
1480
发布2019-05-21 23:20:28
2.3K0
发布2019-05-21 23:20:28
举报
文章被收录于专栏:数据分析1480数据分析1480
前言

在之前的Scala系列中分享了有关数据类型、运算符操作、控制流语法、自定义函数、以及几种集合的使用。慢慢地Scala体系将越来越丰富,在本期内容中将跟各位网友分享Scala的字符串操作和正则表达式的巧用。

字符串操作

字符串是最为常见的一种数据类型,在平时的学习或工作中总能碰见关于字符串的处理,例如字符串的拼接、替换、截取、判断、分割等。接下来对常用的字符串处理做详细讲解,并通过实际的例子加以说明。

字符串的创建

字符串与前几期介绍的列表、元组一样,都属于属于不可变对象,无法通过其方法实现字符串本身的修改。字符串的创建可以使用两种方法,分别是:

双引号法 三对双引号法

我们知道,在Scala中利用单引号可以创建字符对象,而双引号则可以构造字符串对象。但双引号方法构造字符串会存在一个隐患,那就是字符串本身含有双引号是,就会出现语法错误。此时的解决方案就是将双引号换成三引号,而且三引号更强大的地方,可以使字符串多行显示。下面来看几个小例子:

代码语言:javascript
复制
// 字符串自带双引号时,使用双引号构造字符串,出现报错
scala> val S1 = "He says: "see you tomorrow!""
<console>:11: error: value see is not a member of String
       val S1 = "He says: "see you tomorrow!""

// 解决方案,使用三引号
scala> val S2 ="""He says: "see you tomorrow!""""
S2: String = He says: "see you tomorrow!"

// 多行显示字符串值
val S3 ="""大家好,我是刘顺祥。
         |很高兴跟大家分享Scala的点滴知识,
         |感谢大家的支持和鼓励,谢谢!"""
S3: String =
大家好,我是刘顺祥。
很高兴跟大家分享Scala的点滴知识,
感谢大家的支持和鼓励,谢谢!

字符串子串的获取

如需从字符串中获取其中的子部分,可以使用Scala字符串的索引和切片技术。需要注意的是,索引的写法不是中括号[],而是圆括号(),这跟其他编程语言有一些差异。而切片的使用,则调用的是字符串方法slice。相关知识点如下:

charAt:基于位置取出字符串中的某个字符,结果属于Char类型; 索引():等价于charAt的使用; slice切片:从字符串中获取连续的一小段; substring:等同于slice切片的操作;

举例

代码语言:javascript
复制
val price1 = "3元/500g"
println(price1.charAt(0))
3  // 3为Char类型

// 索引方法,如需将字符3转换成整数,必须先转为字符串,
//才可以使用toInt,否则结果有误
println(price1(0).toString.toInt)  
3  // 3为整型

val price2 = "36.2元/500g"
// 切片slice方法中的实参4所对应的值取不到
println(price2.slice(0,4).toDouble) 
36.2

// substring方法的功能等同于slice方法
println(price2.substring(0,4)) 
36.2

// 配合length方法(该方法计算字符长度),
// 灵活使用切片,取出末尾的4个字符
println(price2.slice(price2.length-4, price2.length)) 
500g

字符串的拼接

拼接是指将两个或多个字符串进行首尾相连,实现的方法也很简单,具体如下:

+:字符串之间通过加号实现拼接; concate:利用字符串的concate方法; *:字符串乘以一个整数,指的是字符串的重复

举例

代码语言:javascript
复制
val a = "Hello, "
val b = "Scala!"
println(a + b )
Hello, Scala!

println(a.concat(b))
Hello, Scala!

println(b * 3)  // 重复三遍
Scala!Scala!Scala!

字符串子串位置的查询

在使用切片时可能会碰到开始位置或结束位置的不确定,如果只写上一个固定的整数位置,将无法体现切片的效果。例如价格"23.4元/500g",需要提取出其中的数值23.4,就不能写死切片的开始位置和结束位置,因为万一有"234.5元/500g"的价格就会遇到麻烦。最好的解决方案就是查询字符串中"元"所在的位置,然后再使用切片技术。知识点如下:

indexOf:返回子串首次出现的位置; lastIndexOf:返回子串最后一次出现的位置;

举例

代码语言:javascript
复制
println(b.indexOf("a")) // 返回第一个"a"所在的位置
2

println(b.lastIndexOf("a")) // 返回最后一个"a"所在的位置
4

println(price2.slice(0,price2.indexOf("元")))
36.2

字符串首尾空白的去除

如果在数据清洗过程中,发现字符串的首尾可能存在空白,你可以使用trim方法轻松的将其删除掉,举例如下:

代码语言:javascript
复制
val S4 = "  今天晨跑让自己一天的心情都非常好,明天继续!   "
println(S4.trim)  // 删除字符串首尾空白
今天晨跑让自己一天的心情都非常好,明天继续!

字符串的替换

字符串中子串的替换也是非常常见的一种操作,如需遇到这种情况,你可以使用如下几个字符串方法:

replace:字符串方法,根据指定的值进行替换; replaceFirst:替换第一个满足条件的值,支持正则表达式的使用; replaceAll:替换所有满足条件的值,支持正则表达式的使用;

举例

代码语言:javascript
复制
val S5 = "我是Scala用户,觉得Scala很简单!"
println(S5.replace("Scala","Python"))
我是Python用户,觉得Python很简单!

println(S5.replaceFirst("Scala","Python"))  
我是Python用户,觉得Scala很简单!

println(S5.replaceAll("Scala","Python"))
我是Python用户,觉得Python很简单!

再举一个有意思的小例子,前文中提到,利用三引号可以将长字符串进行多行显示,如果需要将多行的字符串切换到一行显示该如何处理呢?很简单,只需要使用replaceAll方法,将字符串中的换行符"\n"替换为空字符""即可。代码如下:

代码语言:javascript
复制
val S6 = """今天晨跑让自己一天的心情都非常好,
        |明天继续!"""

// stripMargin方法默认以竖线"|"作为分界符,将字符串垂直对齐
println(S6.stripMargin.replaceAll("\n"," "))
今天晨跑让自己一天的心情都非常好, 明天继续!

字符串的分割

有时需要对字符串的内容进行分割,往往分割的时候是需要指定分割符的,最典型的是类似于Excel中的分列操作。在Scala中可以使用如下函数实现字符串的分割:

split:可以指定具体的分割符,也可以指定一个模糊的正则表达式 splitAt:按照字符串的位置进行分割

举例

代码语言:javascript
复制
val S7 = "lsxxx2017@163.com"
println(S7.split('@').toVector) // 根据指定的分隔符将字符串切开
Vector(lsxxx2017, 163.com)

println(S7.split("@").toList) // 支持正则表达式的使用
List(lsxxx2017, 163.com)

println(S7.splitAt(9)) // 根据字符串的位置将字符串切开
(lsxxx2017,@163.com)

字符串的比较

如需判断两个字符串之间是否相等,或者字符串是否以某个子串开头或结尾,可以使用如下几个方法加以实现:

==:判断两者是否相等; equals:等同于双等号法; equalsIgnoreCase:比较时忽略大小写; startsWith:判断字符串是否以某子串开头; endsWith:判断字符串是否以某子串结尾;

举例

代码语言:javascript
复制
val S8 = "Scala"
val S9 = "scala"
println(S8 == S9)
false

println(S8.equals(S9))
false

println(S8.equalsIgnoreCase(S9))
true

println(S9.startsWith("sc"))
true

println(S9.endsWith("sc"))
false

字符串的迭代

字符串属于可迭代对象,可以针对字符串中的每一个字符做相同函数的处理。读者可以使用如下三种方法完成字符串的迭代操作:

foreach:该方法迭代过程中没有返回值; map:有返回值,它是由一个集合到另一个集合的运算; for yield:功能同map方法,而且该方法还可以编写更加复杂的代码;

举例

代码语言:javascript
复制
val S10 = "Spark is based on Scala"
// 必须将foreach出来的每个Char对象做toString的转换,否则出错
S10.foreach(x => print(x.toString.toUpperCase)) 
SPARK IS BASED ON SCALA

println(S10.map(_.toUpper))
SPARK IS BASED ON SCALA

// 由一个集合到另一个集合的运算
val res = for (i <- S10) yield i.toUpper  
println(res)
SPARK IS BASED ON SCALA

字符串的插值

字符串的插值操作类似于Python中字符串的格式化处理,可以在字符串的内部引入变量值,甚至书写数学表达式或者对变量值做格式化输出。Scala中有两种风格的插值方法,一种是s法,另一种是f法:

s格式插值,可以书写变量表达式; f格式插值,除了拥有s法的功能,还可以格式化数据

举例

代码语言:javascript
复制
val name = "Liu"
val height = 165
val weight = 65

println(s"""亲爱的${name}先生,您的身高是${height},体重是${weight},
        |身体质量指数是${weight/((1.0*height/100)*(1.0*height/100))}!""".stripMargin)
亲爱的Liu先生,您的身高是165,体重是65,
身体质量指数是23.875114784205696!

println(f"""亲爱的${name}先生,您的身高是${height},体重是${weight},
        |身体质量指数是${weight/((1.0*height/100)*(1.0*height/100))}%.2f!""".stripMargin)
亲爱的Liu先生,您的身高是165,体重是65,
身体质量指数是23.88!
结语

本期的内容就介绍到这里,下一期的Scala内容讲分享有关正则表达式的使用。如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让更多的人学习和进步。

每天进步一点点:数据分析1480

长按扫码关注我

往期回顾

大数据之脚踏实地学16--Scala列表、元组与映射 大数据之脚踏实地学15--Scala的数组操作 大数据之脚踏实地学14--Scala自定义函数 大数据之脚踏实地学13--Scala控制流

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据分析1480 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 字符串操作
    • 结语
    • 往期回顾
    相关产品与服务
    大数据
    全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档