当前位置: 首页 > news >正文

Scala学习笔记15: 文件和正则表达式

目录

    • 第十五章 文件和正则表达式
      • 1- 读取行
      • 2- 从URL或者其它源读取
      • 3- 写入文本文件
      • 4- 序列化
      • 5- 正则表达式
      • 6- 正则表达式验证输入数据格式
      • end

第十五章 文件和正则表达式

1- 读取行

在Scala中读取文件中的行可以通过不同的方法实现 ;

一种常见的方法是使用 scala.io.Source 对象来逐行读取文件内容 ;

示例 :

import scala.io.Sourceobject FileReadingLinesExample {def main(args: Array[String]): Unit = {val fileName = "src/main/resources/test.txt"try {val source = Source.fromFile(fileName)val lines = source.getLines().toListsource.close()println("文中的行: ")lines.foreach(println)} catch {case e: Exception => println("文件读取错误: " + e.getMessage)}}
}
# 输出
文中的行: 
《登雀鹤楼》
唐.王之涣
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。

在这个示例中, 我首先导入了 scala.io.Source 类 ;

然后, 我们指定要读取的文件名, 并使用 Source.fromFile(fileName) 创建一个 Source 对象 ;

接着, 我们使用 getLines() 方法逐行读取文件内容, 并将每行存储在一个列表中 ;

最后, 我们关闭文件流并打印出读取的所有行 .

注意, 这只是一个简单的示例, 实际应用中可能需要更多的错误处理和资源管理 ;

确保文件存在并具有适当的读取权限 ;

你可以根据需要进一步扩展和优化这段代码 .

2- 从URL或者其它源读取

在Scala中, 你可以使用 scala.io.Source 类来从URL或其他来源读取文件内容 ;

示例 :

import scala.io.Source
import java.net.URLobject URLReadingExample {def main(args: Array[String]): Unit = {val url = new URL("https://raw.githubusercontent.com/dpx0110/files/main/poem.txt")try {val source = Source.fromURL(url)val content = source.mkStringsource.close()println("从URL读取的文件内容: ")println(content)} catch {case e: Exception => println(s"Error reading URL: ${e.getMessage}")}}
}
  • 在这个示例中, 我们导入了 scala.io.Source 类和 java.net.URL 类 ;
  • 然后, 我们创建一个 URL 对象, 指定要读取的URL地址 ;
  • 接着, 我们使用Source.fromURL(url) 方法从URL读取文件内容, 并将其存储为字符串 ;
  • 最后, 我们关闭文件流并打印出读取的内容 .
// 其它源读取
val source1 = Source.fromString("hello world! ")
val source2 = Source.stdin
...

请确保URL地址有效并具有适当的访问权限 ;

根据实际情况修改URL地址, 以适应你的文件读取需求 ;

这段代码可以帮助你从URL或其他来源读取文件内容 .

3- 写入文本文件

在Scala中写入文本文件, 可以使用多种方法, 一下是几种常见方式 :

**1. 使用 java.io.PrintWriter **

这是最直接的方式, 利用 Java 的 PrintWriter 类写入数据到文件 ;

import java.io.PrintWriterobject WriteToFile {def main(args: Array[String]): Unit = {val filePath = "src/main/resources/poem1.txt"val writer = new PrintWriter(filePath)try {writer.println("《题西林壁》")writer.println("宋.苏轼")writer.println("横看成岭侧成峰,")writer.println("远近高低各不同。")writer.println("不识庐山真面目,")writer.println("只缘身在此山中。")} finally {writer.close()}}
}
《题西林壁》
宋.苏轼
横看成岭侧成峰,
远近高低各不同。
不识庐山真面目,
只缘身在此山中。

2. 使用 java.io.FileWriterjava.io.BufferedWriter

这种方式更注重效率, BufferedWriter 可以提高写入效率, 尤其在处理大量数据时 ;

import java.io.{BufferedWriter, FileWriter}object WriteToFile {def main(args: Array[String]): Unit = {val filePath = "src/main/resources/poem2.txt"val writer = new FileWriter(filePath)val bufferedWriter = new BufferedWriter(writer)try {bufferedWriter.write("《题西林壁》\n") // 须手动添加换行符bufferedWriter.write("宋.苏轼\n")bufferedWriter.write("横看成岭侧成峰,\n")bufferedWriter.write("远近高低各不同。\n")bufferedWriter.write("不识庐山真面目,\n")bufferedWriter.write("只缘身在此山中。\n")} finally {bufferedWriter.close()}}
}
《题西林壁》
宋.苏轼
横看成岭侧成峰,
远近高低各不同。
不识庐山真面目,
只缘身在此山中。

4- 序列化

在分布式系统、大数据处理以及需要将对象状态保存到磁盘的场景中, 序列化扮演着至关重要的角色 ;

Scala作为一门运行于Java虚拟机上的语言, 自然也需要处理对象的序列化和反序列化问题 ;

Scala本身没有提供原生的序列化机制, 而是依赖于Java的序列化机制或第三方库来实现 ;

1. 使用Java序列化

最直接的方式是使用Java自带的序列化机制 ;

你只需要让你的类继承 java.io.Serializzble 接口 , 并添加 serialVersionUID 即可 ;

    // 序列化 和 反序列化import java.io._@SerialVersionUID(100L)class Person(val name: String, val age: Int) extends Serializable {override def toString: String = s"Person(name=$name, age=$age)"}// 序列化val person = new Person("Tom", 18)val outputStream = new FileOutputStream("person.ser")val objectOutputStream = new ObjectOutputStream(outputStream)objectOutputStream.writeObject(person)objectOutputStream.close()// 反序列化val inputStream = new FileInputStream("person.ser")val objectInputStream = new ObjectInputStream(inputStream)val loadedPerson = objectInputStream.readObject().asInstanceOf[Person]objectInputStream.close()println(loadedPerson) // Output: Person(name=Tom, age=18)println(loadedPerson.getClass) // Output: class org.puture.scala.MyFiles$Person$1println(loadedPerson.name) // Output: Tomprintln(loadedPerson.age) // Output: 18
  • 优点: 简单直接, 开箱即用
  • 缺点:
    • 只能序列化实现了 java.io.Serializable 接口的类
    • 序列化后的数据格式与Java绑定, 不够灵活
    • 性能相对较低

2. 使用第三方库

为了克服Java序列化的缺点, Scala社区涌现出许多优秀的第三方序列化库, 例如:

  • Json库:
    • uPickle: 专注于速度和简洁性, 使用宏生成高效的序列化代码 ;
    • Circe: 类型安全, 功能强大, 支持多种数据格式 ;
    • Play Json: Play框架的一部分, 易于使用, 适用于Web应用程序 ;
  • 其他库:
    • Kryo: 高性能序列化库, 适用于需要极致速度的场景 ;
    • Chill: Twitter开发的序列化库, 支持多种数据格式, 包括Kryo和Json .

选择合适的序列化方式

选择哪种序列化方式取决于你的具体要求 :

  • 简单项目: 如果你的项目比较简单, 对性能要求不高, 可以使用Java序列化或者uPickle ;
  • **Web应用程序: ** 可以考虑使用Play Json, 它与Play框架集成良好 ;
  • **高性能需求: ** 如果你的项目对性能要求很高, 可以考虑使用Kryo或者Chill ;
  • **类型安全: ** 如果需要类型安全的序列化, 建议使用 Circe等库 ;

总而言之, Scala提供了多种方式类处理对象的序列化和反序列化, 你需要根据项目的具体情况选择合适的方式 .

5- 正则表达式

Scala中的正则表达式使用与 Java相同的语法, 但它提供了更简洁、更强大的方式来匹配和操作文本 ;

1. 基本语法

Scala中的正则表达式使用 r 字符串字面量来定义 ; 例如 :

val regex = "hello".r

这个正则表达式将匹配字符串 “hello” ;

2. 常用元字符

  • . : 匹配任意单个字符 ;
  • * : 匹配前面的字符零次或多次 ;
  • + : 匹配前面的字符一次或多次 ;
  • ? : 匹配前面的字符零次或一次 ;
  • | : 匹配左边或右边的表达式 ;
  • [] : 匹配方括号内的任意字符 ;
  • [^...] : 匹配不在方括号内的任意字符 ;
  • \d : 匹配数字 ;
  • \s : 匹配空白字符 ;
  • \w : 匹配字母、数字或才划线 ;
  • \b : 匹配单词边界 ;
  • ^ : 匹配字符串开头 ;
  • $ : 匹配字符串结尾 ;

3. 匹配文本

可以使用 findAllIn 方法来查找匹配的文本 ;

    val text = "Hello, world!"val regex = "Hello".rval matches = regex.findAllIn(text)matches.foreach(println) // 输出: Hello	

4. 替换文本

可以使用 replaceAllIn 方法来替换匹配的文本 ;

    val text = "Hello, world!"val regex = "world".rval replaced = regex.replaceAllIn(text, "Scala")println(replaced) // Output: Hello, Scala!

5. 分组

可以使用 () 来分组正则表达式, 并通过 group 方法获取匹配的子字符串 ;

    val text = "The quick brown fox jumps over the lazy dog."val regex = "(.+) (.+) (.+)".rval matches = regex.findAllMatchIn(text)matches.foreach(m => {println("Group 1: " + m.group(1)) // Group 1: The quick brown fox jumps over theprintln("Group 2: " + m.group(2)) // Group 2: lazyprintln("Group 3: " + m.group(3)) // Group 3: dog.})

6. 捕获组

可以使用 find 方法来查找第一个匹配的文本, 并使用 group 方法获取捕获组的内容 ;

    val text = "The quick brown fox jumps over the lazy dog."val regex = "(\\w+) (\\w+)".rval matches = regex.findPrefixOf(text)println(matches) // Output: Some(The quick)if (matches.isDefined) {val m = matches.getprintln(m) // Output: The quick}

7. 注意事项

  • 正则表达式语法较为复杂, 需要仔细理解才能灵活运用 ;
  • 正则表达式匹配效率可能较低, 特别是复杂的表达式, 需要谨慎使用 ;
  • Scala 中的正则表达式支持Java的正则表达式语法, 可以参考Java文档了解更多细节 ;

总结

Scala中的正则表达式功能强大, 能够满足各种文本匹配和处理的需求 ;

希望以上介绍能够帮助你更好的理解Scala中的正则表达式 .

6- 正则表达式验证输入数据格式

在Scala中, 你可以使用正则表达式来验证输入数据的格式, 例如邮箱地址、手机号等 ;

1. 准备工作

首先, 需要定义一个正则表达式, 用来匹配目标格式的数据 ;

例如:

  • 邮箱地址: ^.+@.+\\..+$
  • 手机号: ^1[3-9]\\d{9}$

2. 代码示例

object DataValidation {def main(args: Array[String]): Unit = {val emailRegex = "^.+@.+\\..+$".rval phoneRegex = "^1[3-9]\\d{9}$".r// 键盘输入println("请输入邮箱地址:")val email = scala.io.StdIn.readLine()println("请输入手机号:")val phone = scala.io.StdIn.readLine()// 验证邮箱地址if (emailRegex.findFirstIn(email).isDefined) {println("邮箱地址格式正确")} else {println("邮箱地址格式错误")}// 验证手机号if (phoneRegex.findFirstIn(phone).isDefined) {println("手机号格式正确")} else {println("手机号格式错误")}}
}
请输入邮箱地址:
6666@gmail.com
请输入手机号:
16688889999
邮箱地址格式正确
手机号格式正确Process finished with exit code 0请输入邮箱地址:
123.34@gamil.com
请输入手机号:
166888899996
邮箱地址格式正确
手机号格式错误Process finished with exit code 0

3. 解释

  • Regex 类是Scala用于表示正则表达式的类 ;
  • findFirstIn 方法用于查找字符串中第一个匹配正则表达式的字符串, 如果找到则返回 Some(匹配的自字符串) , 否则返回 None ;
  • isDefined 方法用于判断 Option 类型的值是否为空 ;

4. 其它验证方法

除了使用 findFirstIn 方法, 还可以使用以下方法来验证数据格式 :

  • matches 方法: 判断整个字符串是否匹配正则表达式 ;
  • replaceAllIn 方法: 将字符串中所有匹配正则表达式的部分替换成其他字符串 ;

5. 注意事项

  • 正则表达式语法比较复杂, 需要仔细学习和理解 ;
  • 使用正则表达式进行数据格式验证只能保证数据符合预期的格式, 无法保证数据的有效性 ;
  • 例如: 验证有序地址格式, 并不能保证这个邮箱地址真实存在 ;

6. 扩展

除了验证邮箱地址和手机号, 还可以使用正则表达式来验证其他格式的数据, 例如:

  • 日期格式
  • 身份证号码
  • 邮政编码
  • URL地址

end

http://www.lryc.cn/news/391991.html

相关文章:

  • 外卖员面试现状
  • 异步加载与动态加载
  • MUNIK解读ISO26262--什么是DFA
  • 启动spring boot项目停止 提示80端口已经被占用
  • SOLIDWORKS分期许可(订阅形式),降低前期的投入成本!
  • 详细分析Spring Boot 数据源配置的基本知识(附配置)
  • 海思SD3403/SS928V100开发(15)9轴IMU ICM-20948模块SPI接口调试
  • 大力出奇迹:大语言模型的崛起与挑战
  • 【算法 - 哈希表】两数之和
  • 【深度学习】图形模型基础(5):线性回归模型第一部分:认识线性回归模型
  • 2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛B题超详细解题思路+数据预处理问题一代码分享
  • Yarn有哪些功能特点
  • 深度学习算法bert
  • PyTorch - 神经网络基础
  • docker-compose搭建minio对象存储服务器
  • vue3使用pinia中的actions,需要调用接口的话
  • Python酷库之旅-第三方库Pandas(003)
  • 社交电商中的裂变营销利器,二级分销模式,美妆家具成功案例分享
  • 【国产开源可视化引擎Meta2d.js】图层
  • 基于Redisson实现分布式锁
  • Android Studio下载Gradle特别慢,甚至超时,失败。。。解决方法
  • leetcode--二叉树中的最长交错路径
  • c++ primer plus 第15章友,异常和其他:15.1.3 其他友元关系
  • uniapp+vue3页面跳转和传参
  • 硬链接和软链接
  • 属性描述符初探——Vue实现数据劫持的基础
  • 字节也没余粮了?天底下没有永远免费的GPT-4;AI产品用订阅制就不合理!让用户掏钱的N种定价技巧嘿嘿 | ShowMeAI日报
  • 【Matlab 路径优化】基于蚁群算法的XX市旅游景点线路优化系统
  • 我关于Excel使用点滴的笔记
  • 【Java安装】windows10+JDK21+IDEA