原文发表于:http://nerd-is.in/2013-08/scala-learning-files-and-regular-expressions
读取文件
|
importscala.io.Source
valsource=Source.fromFile(fileName,"UTF-8")
// 第一个参数可以是文件名或java.io.File
// 如果没有第二个参数将会使用当前平台缺省的字符编码
vallineIterator=source.getLines // 结果是一个迭代器
// 迭代器可以转换成Array等
valcontents=source.mkString // 整个文件读取成一个字符串
|
使用完Source后,记得需要close。
读取字符
要读取单个字符,可以直接从Source对象中进行迭代。Source类扩展自Iterator[Char]。
如果想要查看接下来的字符,但是不对其进行处理(也就是说迭代器不移动位置),可以调用Source的buffered方法,返回一个collection.BufferedIterator[Char],然后使用这个对象的head方法查看下一个字符。
|
valsource=Source.fromFile("myfile.txt","UTF-8")
valiter=source.buffered
while(iter.hasNext){
if(iter.head==someChar)
deal withiter.next
else
...
}
source.close()
|
读取词法单元和数字
|
// 一个快而脏的方式
valtokens=source.mkString.sqlit("\\s+") // 根据正则读取词法单元
// 转换成数字
valnumbers=for(w<-tokens)yieldw.toDouble
valnumbers=tokens.map(_.toDouble)
|
还可以使用java.util.Scanner类来读取文件中的文本和数字。
从非文件源读取
|
// 从URL读取,需要注意字符编码
valsource1=Source.fromURL("http://horstmann.com","UTF-8")
valsource2=Source.fromString("Hello, world!") // 从指定的字符串读取,调试时很有用
valsource3=Source.stdin // 从标准输入读取
|
读取二进制文件
Scala没有提供读取二进制文件的方法,需要使用Java类库。
|
valfile=newFile(filename)
valin=newFileInputStream(file)
valbytes=newArray[Byte](file.length.toInt)
in.read(bytes)
in.close()
|
写入文本文件
Scala也没有对写入文件的内建支持,依旧可以使用Java类库来实现。如:
|
valout=newPrintWriter("numbers.txt")
for(i<-1to100)out.println(i)
out.close()
|
但是在使用这里printf方法时,传递AnyVal(比如各种数字)类型给方法时,编译器会要求将其转换成AnyRef:
|
out.printf("%6d %10.2f",quantity.asInstanceOf[AnyRef],
price.asInstanceOf[AnyRef])
// 为了避免这个麻烦,可以使用String类的format方法
out.printf("%6d %10.2f".format(quantity,price))
|
访问目录
目前没有“正式的”用来访问目录中所有文件,或递归遍历所有目录的类。(本章各种没有内建没有正式是闹哪样啊!也无所谓了,用Java类库就是了。)下面探讨一下替代方案。
遍历某目录下所有子目录的函数:
|
importjava.io.File
defsubdirs(dir:File):Iterator[File]={
valchildren=dir.listFiles.filter(_.isDirectory)
children.toIterator++children.toIterator.flatMap(subdirs_)
}
|
不是很好懂,可能需要查阅API文档来帮忙。
如果使用了Java 7,可以使用java.nio.file.Files类的walkFileTree方法。该类用到了FileVisitor接口。
这里提到了Java的nio包,让我记起来的确需要去学一学了,io包大概已经真满足不了现在的需求了。
在Scala中通常更偏好用函数对象来指定工作内容,而不是接口(但在本例中接口可以有更细粒度的控制)。
以下隐式转换让函数可以与接口相匹配:
|
importjava.nio.file._
implicitdefmakeFileVisitor(f:(Paht)=>Unit)=newSimpleFileVisitor[Path]{
overridedefvisitFile(p:Path,attrs:attribute.BasicFileAttributes)={
f(p)
FileVisitResult.CONTINUE
}
}
// 调用打印出所有的子目录
Files.walkFileTree(dir.toPaht,(f:Path)=>println(f))
|
这个真心有点超出太多了,放着先吧,等学了相关的知识再回来看。
序列化
使用序列化来将对象传输,或者是临时存储,序列化并不适合长期存储,会因为类的更新而出现问题。
在Scala中的序列化类:
|
@SerialVersionUID(42L)classPerson extendsSerializable
|
如果可以接受缺省的UID,可以不要@SerialVersionUID注解。
序列化和反序列化:
|
valfred=newPerson(...)
importjava.io._
valout=newObjectOutputStream(newFileOutputStream("/tmp/test.obj"))
out.writeObject(fred)
out.close()
valin=newObjectInputStream(newFileInputStream("/tmp/test.obj"))
valsavedFred=in.readObject().asInstanceOf[Person]
in.close()
|
进程控制(A2)
Scala设计目标之一是能在简单的脚本话任务和大型程序之间保持良好的伸缩性。
scala.sys.process包提供了用于与shell程序交互的工具。这样一来,就可以使用Scala编写shell脚本。(虽然我用了Linux不少时间了,但我还是不会bash编程啊!怎么会有这么多东西需要学啊!~来不及的感觉…)
简单例子:
|
importsys.process._
"ls -al .."!
|
ls -al ..命令将会被执行,然后将结果在标准输出中显示。
sys.process包内有从字符串到ProcessBuilder对象的隐式转换。!操作符执行的就是这个ProcessBuilder对象。返回的结果是被执行程序的返回值:成功执行是0;否则是显示错误的非0值。
如果使用!!操作符,输出会以字符串的形式返回:
还可以使用管道(不了解什么是管道的,请先学习一下Linux基础),使用#!操作符。
|
// 管道,使用#|
"ls -al .."#|"grep sec"!
// 重定向到文件,使用#>
"ls -al .."#>newFile("output.txt")!
// 追加到文件,使用#>>
"ls -sl .."#>>newFile("output.txt")!
// 将文件内容作为输入,使用#<
"grep sec"#<newFile("output.txt")! // 也可以使用URL
|
另外还可以使用#||和#&&来控制进程。不过这种功能还是直接使用Scala来实现更好。
可以自己指定执行进程的目录和环境变量;设置环境变量用的是一系列的对偶。
|
valp=Process(cmd,newFile(dirName),("LANG","en_US"))
"echo 42"#|p! // 执行
|
个人认为这个功能还是很强大的,可以使用现有的命令来做到大量的事情。不过是否会带来安全上的影响,以及可能会使程序变得与平台有关,还是要慎重使用。
正则表达式
与正则表达式相关的类是scala.util.matching.Regex类。要构造一个Regex对象,使用String类的r方法即可。如果正则表达式中包含反斜杠或引号之类的需要转义的字符,那么最好是使用原始(raw)字符串,以三个”号包围。
|
valnumPattern="[0-9]+".r
valwsnumwsPattern="""\s+[0-9]+\s+""".r
|
|
// findAllIn方法返回遍历所有匹配项的迭代器
for(matchString<-numPattern.findAllIn("99 bottles, 98 bottles"))
// 找到首个匹配项
valm1=wsnumwsPattern.findFirstIn("99 bottles, 98 bottles")
// 返回Some(" 98 ")
// findFirstIn方法返回Option[String]
|
用findPrefixOf方法检查某个字符串的开始部分是否能够匹配。
可以用相应的replace方法来替换掉匹配的部分。
正则表达式组
分组使得获取正则表达式的子表达式更加方便。在想要提取的子表达式两侧加上圆括号:
|
valnumitemPattern="([0-9]+) ([a-z]+".r
|
匹配组将正则表达式对象当做“提取器”来使用:
|
valnumitemPattern(num,item)="99 bottles"
// num被赋值为"99",item被赋值为"bottles"
|
相关推荐
Scala 正则表达式是 Scala 语言中的一种强大工具,用于模式匹配和字符串处理。在 Scala 中,正则表达式可以通过两种方式创建:通过 `r` 方法直接将字符串转换成正则表达式对象,或者直接显式地调用 `Regex` 构造函数...
关于 reb4s reb4s的目的是围绕 JRE 的类提供的正则表达式语法提供一个纯 Scala 包装器。 它是一个分支,它通过纯 Java API 提供相同的功能。 与直接编写正则表达式相比,reb4s具有以下优点: reb4s API 保证正确的...
Scala文件读写操作与正则表达式 Scala语言提供了多种文件读写操作的方式,包括读取文本文件、读取二进制文件等。在Scala中,可以使用scala.io.Source对象来读取文件,该对象提供了多种方法来读取文件,例如getLines...
正则表达式(Regular Expression,简称regex、regexp或RE)是一种文本模式,它由普通字符(如a到z之间的字母)和特殊字符(称为“元字符”)组成,用于描述、匹配一系列符合某个句法规则的字符串。正则表达式是对...
这是一款正则匹配工具,正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个...
在Java中使用Scala进行...总的来说,Scala的正则表达式功能强大且灵活,对于处理文本数据和进行模式匹配是非常有用的工具。理解并熟练运用这些规则,可以极大地提升在Java环境中使用Scala进行文本处理的效率和准确性。
高尔夫球该项目旨在从作为输入提供的已知样本集生成正则表达式。 这并不是正则表达式高尔夫问题所期望的。 对于不熟悉的人,regex Golf 希望用户提出一个与允许列表中的一组单词相匹配的正则表达式,而不应该与不...
粗略的技巧,以可视化OpenJDK如何匹配正则表达式。 输出将是一个HTML文件,该文件允许逐步执行匹配过程。 怎么跑 ./gradlew run 生成的跟踪将被写入当前工作目录中的report.html文件中。 请注意,仅使用OpenJDK 8、...
在Scala中,正则表达式是处理文本模式匹配的强大工具,它能够识别和操作字符串中的复杂模式。Scala的模式匹配提供了一种灵活的方式来对数据进行解构和分类,当与正则表达式结合时,这种能力得到了极大的提升。 首先...
正则表达式(又名regex,regexp)变得容易。 这个简单的工具可以使用正则表达式来处理文本。 正则表达式结果的突出显示。 看看正则表达式的真正力量! 使用Scala甚至可以更多地操纵您的搜索结果。
然后,您可以在任何位置使用Scala中的模式,使用万花筒正则表达式(以字母r开头的字符串)。 例如, path match case r " /images/.* " => println( " image " ) case r " /styles/.* " => println( " stylesheet...
Scala 正则表达式 Scala 通过 scala.util.matching 包中的 Regex 类来支持正则表达式。以下实例演示了使用正则表达式查找单词 Scala : import scala.util.matching.Regex object Test { def main(args: Array...
dr 从正则表达式中获取更多有用的信息: scala > import io . expressier . _import io . expressier . _scala > case class Item ( name : String , x : Int , c : Char , s : String )defined class Itemscala > ...
ScalaFX程序将网页上的正则表达式(即产品价格)选择的内容与文本文件中的列表进行比较。 状态 可用的。 要求 Java运行时= Java 8 运行目录中所需的文件 所有文件均为UTF-8(无BOM) “ pricecompare.exe”...
cron4s是一个专门为Scala设计的库,它提供了一个强大的、跨平台的解决方案,用于解析和操作CRON(Cron)表达式。CRON是Unix/Linux系统中广泛使用的定时任务调度工具,通过特定的语法来定义周期性的任务。cron4s库...
kantan.regex是Scala语言中的一个正则表达式库,它提供了更高级和方便的API来处理正则表达式操作。"laws"部分通常在软件开发中指的是用于验证库行为的一系列测试,确保其遵循预期的数学或逻辑规则。 描述 "grpc-...