Scala使用與Java相同的規則表示式(Regular Expression)語法,你可以在 java.util.regex.Pattern 找到語法說明。
以下先介紹幾個簡單的正則表示式。一些常用的範圍,可以使用預先定義的字元類別:
. | 符合任一字元 |
\d | 等於 [0-9] 數字 |
\D | 等於 [^0-9] 非數字 |
\s | 等於 [ \t\n\x0B\f\r] 空白字元 |
\S | 等於 [^ \t\n\x0B\f\r] 非空白字元 |
\w | 等於 [a-zA-Z_0-9] 數字或是英文字 |
\W | 等於 [^a-zA-Z_0-9] 非數字與英文字 |
. 符合任一字元。例如有一字串abcdebcadxbc,使用.bc來比對的話,符合的子字串有abc、ebc、xbc三個;如果使用..cd,則符合的子 字串只有bcd。
以上的例子來根據字元比對,也可以使用「字元類」(Character class)來比較一組字元範圍,例如:
[abc] | a、b或c |
[^abc] | 非a、b、c的其它字元 |
[a-zA-Z] | a到z或A到Z(範圍) |
[a-d[m-p]] | a到d或m到p(聯集) |
[a-z&&[def]] | d、e或f(交集) |
[a-z&&[^bc]] | a到z,除了b與c之外(減集) |
[a-z&&[^m-p]] | a到z且沒有m到p(a-lq-z)(減集) |
可以用Greedy quantifiers來 指定字元可能出現的次數:
X? | X出現一次或完全沒有 |
X* | X出現零次或多次 |
X+ | X出現一次或多次 |
X{n} | X出現n次 |
X{n,} | X出現至少n次 |
X{n,m} | X出現至少n次,但不超過m次 |
字串物件擁有matches()方法可以讓您驗證字串是否符合指定的規則表示式,這通常用於驗證使用者輸入的字串資料是否正確,例如電話號碼格式; replaceAll()方法可以將符合規則表示式的子字串置換為指定的字串;split()方法可以依指定的規則表示式,將符合的子字串分離出來,並以 字串陣列傳回。
在Scala中若要建立可重複使用的規則表示式物件,可使用 scala.util.matching.Regex 類別,例如:
import scala.util.matching.Regex
val yp = new Regex("\\d\\d\\d\\d")
val year = yp.findFirstIn("Birthday: 1975/05/26")
println(year.getOrElse("沒有年份資訊")) // 1975
如果你在"與"間定義規則表示式,那麼對於\d的第一個\字元,你必須避開(Escape),也就是寫為\\d的形式,如果你不想特意作避開字元的動作,則可以在"""與"""定義規則表示式,例如:
import scala.util.matching.Regex
val yp = new Regex("""\d\d\d\d/\d\d/\d\d""")
val year = yp.findFirstIn("Birthday: 1975/05/26")
println(year.getOrElse("沒有年份資訊")) // 1975/05/26
事實上,你可以更簡便地利用 scala.runtime.RichString 的 r 方法來建立規則表示式:
val yp = """(\d\d\d\d)/(\d\d)/(\d\d)""".r
val year = yp.findFirstIn("Birthday: 1975/05/26")
println(year.getOrElse("沒有年份資訊")) // 1975/05/26
當你使用()將規則表示式中某些規則群組起來時,你可以運用提取器的語法來提取符合的元素,例如:
val Birthday = """(\d\d\d\d)/(\d\d)/(\d\d)""".r
val Birthday(y, m, d) = "1975/05/26"
printf("%s 年 %s 月 %s 日%n", y, m, d) // 1975 年 05 月 26 日
如果()被設定為可出現零次的情況,若要比對的字串沒有出現,則提取出null值,例如:
val Birthday = """(\d\d\d\d)?/?(\d\d)/(\d\d)""".r
val Birthday(y1, m1, d1) = "1975/05/26"
printf("%s 年 %s 月 %s 日%n", y1, m1, d1) // 1975 年 05 月 26 日
val Birthday(y2, m2, d2) = "05/26"
printf("%s 年 %s 月 %s 日%n", y2, m2, d2) // null 年 05 月 26 日
之所以可以使用這樣的提取器語法,是因為 scala.util.matching.Regex 類別定義了unapplySeq()方法,對於符合規則表示式中使用()群組的部份提取出來。