Scala學習(九)文件和正則表達式

1.讀取行

要想讀取文件中的全部行,能夠調用scala.io.Source對象的getLines方法:html

注:讀取文件的指定編碼必需要和文件編碼對應,不然執行報錯:Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1。在使用完Source對象以後,記得調用close方法。java

2.讀取字符

要從文件中讀取單個字符,你能夠直接把Source對象當作迭代器,由於Source類擴展自Iterator[Char]:正則表達式

若是你想查看某個字符但又不處理掉她的話,調用source對象的buffered方法。這樣你就能夠用head方法或者next方法查看寫一個字符,但同時並不把他當作是已處理的字符。shell

3.讀取詞法單元和數字

這裏有一個很是簡便而快捷的方式來讀取原文件中全部以空格隔開的詞法單元:網頁爬蟲

val tokens = source.mkString.split("\\s+")

而要吧字符串轉換成數字,能夠用toInt或toDouble方法。若是你有一個浮點數的文件,則能夠將他們通通讀取到數組中:數組

val numbers = for(w <- tokens) yield w.toDouble

或者工具

val numbers = tokens.map(_.toDouble)

提示:你老是可使用java.util.Scanner類來處理同時包含文本和數字的文件。ui

4.寫一個網頁爬蟲

爬網頁源代碼編碼

用正則爬頁面連接spa

5.從URL或其餘源讀取

Source對象有讀取非文件源的方法:

val source = Source.fromURL("http://horstamnn.com","UTF-8")

val source2 = Source.fromString("Hello,World!") //從給定字符串讀取,對調試頗有用

val source = Source.stdin //從標準輸入讀取

6.讀取二進制文件,寫入文本文件,訪問目錄

Scala並無提供讀取二進制文件的方法。你須要使用Java類庫。

Scala沒有內建的對寫入文件的支持。要寫入文本文件,可使用java.io.PrintWriter。

Scala並無「正式的」用來訪問某個目錄中全部文件或者遞歸遍歷全部目錄的類。最簡單的方式是使用java.nio.file包中的Files.list和Files.walk方法。

list方法訪問目錄的直接後代,walk方法訪問全部後代。

7.序列化

如下是如何在Java和Scala中聲明一個可序列化的類。

Java:

public class Person implements java.iio.Serializable {
    private static final long serialVersionUID = 42L;

}

Scala:

@SerialVersionUID(42L) class Person extends Serializable

Serializable特質定義在scala包,所以不須要顯式引入。

說明:若是你能接受缺省的ID,所以不須要@SerialVersionUID註解。

8.進程控制

Scala的設計目標之一就是能在簡單的腳本化任務和大型程序之間保持良好的伸縮性。scala.process包提供了用於與shell程序交互的工具。能夠利用Scala編寫shell腳本,利用Scala提供的全部威力。

以下是一個簡單的實例:

import sys.process._
"ls -al .." !

這樣作的結果是,ls -al ..命令被執行,顯示上層目錄中的全部文件。

sys.process包含了一個從字符串到ProcessBuilder對象的隱式轉換。!操做符執行的就是這個ProcessBuilder對象。

!操做符返回的結果是被執行程序的返回值:程序成功執行的話就是0,不然就是顯示錯誤的非0值。

若是使用!!,輸出會以字符串的形式返回。

val result = "ls -al .." !!

要把輸出重定向到文件,使用#》操做符:

"ls -al .." #> new File("output.txt") !

要追到到文件末尾而不是從頭覆蓋的話,使用#>>操做符:

"ls -al .." #>> new File("output.txt") !

要把某個文件的內容做爲輸入,使用#<  :

"ls -al .." #< new File("output.txt") !

從URL重定向輸入:

"grep Scala" #< new URL("http://horstmann.com/index.html") !

說明:進程庫使用人們熟悉的shell操做符 | > >> < && || ,只不過給它們加上了#前綴,所以他們的優先級是相同的。

9.正則表達式

Scala 經過 scala.util.matching 包中的 Regex 類來支持正則表達式。如下實例演示了使用正則表達式查找單詞 Scala :

import scala.util.matching.Regex

object Test {
    def main(args: Array[String]) {
        val pattern = "Scala".r
        val str = "Scala is Scalable and cool"
        println(pattern findFirstIn str)
    }
}

執行以上代碼,輸出結果爲:

$ scalac Test.scala
$ scala Test
Some(Scala)

實例中使用 String 類的 r() 方法構造了一個Regex對象。

而後使用 findFirstIn 方法找到首個匹配項。

若是須要查看全部的匹配項可使用 findAllIn 方法。

你可使用 mkString( ) 方法來鏈接正則表達式匹配結果的字符串,並可使用管道(|)來設置不一樣的模式:

import scala.util.matching.Regex

object Test {
    def main(args: Array[String]) {
        val pattern = new Regex("(S|s)cala") // 首字母能夠是大寫 S 或小寫 s
        val str = "Scala is scalable and cool"
        println((pattern findAllIn str).mkString(",")) // 使用逗號 , 鏈接返回結果
    }
}

執行以上代碼,輸出結果爲:

$ scalac Test.scala
$ scala Test
Scala,scala

若是你須要將匹配的文本替換爲指定的關鍵詞,可使用 replaceFirstIn( ) 方法來替換第一個匹配項,使用 replaceAllIn( ) 方法替換全部匹配項,實例以下:

import scala.util.matching.Regex

object Test {
    def main(args: Array[String]) {
        val pattern = "(S|s)cala".r
        val str = "Scala is scalable and cool"
        println(pattern replaceFirstIn(str, "Java"))
    }
}

執行以上代碼,輸出結果爲:

$ scalac Test.scala
$ scala Test
Java is scalable and cool

在 Java 和 Scala 中字符串中的反斜線是轉義字符。因此若是你要輸出 .\.,你須要在字符串中寫成 .\\. 來獲取一個反斜線。查看如下實例:

import scala.util.matching.Regex

object Test {
    def main(args: Array[String]) {
        val pattern = new Regex("abl[ae]\\d+")
        val str = "ablaw is able1 and cool"
        println((pattern findAllIn str).mkString(","))
    }
}

執行以上代碼,輸出結果爲:

$ scalac Test.scala
$ scala Test
able1

Regex對象API經常使用API:

    findAllIn 返回遍歷全部匹配項

    findFirstin 返回字符串中首個匹配項

    findPrefixOf 檢查是否某個字符串的開始部分能匹配

    replaceFirstIn 替換首個匹配項

    replaceAllIn 替換所有匹配項

10.正則表達式組

分組可讓咱們方便地獲取正則表達式的子表達式。在你想要提取的子表達式兩側加上圓括號,例如:

val numitemPattern = " ([0-9]+) ([a-z]+) ".r

要匹配組,能夠把正則表達式對象當作"提取器"使用,就像這樣:

val numitemPattern (num, item) = "99 bottles" // 將num設爲"99",item設爲"bottles"

若是你想要從多個匹配項中提取分組內容,能夠像這樣使用for語句:

for (numitemPattern (num,item) <- numitemPattern.findAllln("99 bottles, 98 bottles"))

處理num和item

相關文章
相關標籤/搜索