2017-07-11 40 views
3

我用Regex.fromLiteral(".*")創建了一個非常簡單的match-all正則表達式。正則表達式與Regex.fromLiteral()匹配創建了什麼?

根據documentation:「返回指定文字字符串的文字正則表達式。」

但我真的不明白「爲指定的文字字符串」應該是什麼意思。

考慮這個例子:

fun main(args: Array<String>) { 
    val regex1 = ".*".toRegex() 
    val regex2 = Regex.fromLiteral(".*") 
    println("regex1 matches abc: " + regex1.matches("abc")) 
    println("regex2 matches abc: " + regex2.matches("abc")) 
    println("regex2 matches .* : " + regex2.matches(".*")) 
} 

輸出:

regex1 matches abc: true 
regex2 matches abc: false 
regex2 matches .* : true 

如此明顯(而且違背了我的期望),Regex.fromLiteral()String.toRegex()行爲完全不同的(我已經嘗試了幾十種不同的參數regex2.matches() - 唯一返回true的是.*

Doe這意味着用Regex.fromLiteral()創建的正則表達式總是僅匹配確切的字符串它是用?創建的?

如果是,那麼這樣的正則表達式有哪些可能的用例? (我想不出任何有用的場景)

回答

4

是的,這確實建立符合該String文字字符的正則表達式。當你試圖匹配在正則表達式中被解釋的符號時,這很方便 - 你不必以這種方式逃避它們。

例如,如果你正在尋找包含.*[](1)?[2]字符串,你可以做到以下幾點:

val regex = Regex.fromLiteral(".*[](1)?[2]") 

regex.containsMatchIn("foo")     // false 
regex.containsMatchIn("abc.*[](1)?[2]abc") // true 

當然,你幾乎可以做任何事情,你可以做一個Regex只有普通String方法太。

val literal = ".*[](1)?[2]" 
literal == "foo"      // equality checks 
literal in "abc.*[](1)?[2]abc"   // containment checks 
"some string".replace(literal, "new") // replacements 

但有時你需要一個Regex實例作爲參數,所以fromLiteral方法可以在這些情況下使用。針對不同輸入的這些不同操作的執行對於某些用例也可能是有意義的。

+1

「有時你需要一個Regex實例作爲參數」 - 真的,沒有想到這種情況。謝謝! –

3

Regex.fromLiteral()實例化一個正則表達式對象,同時轉義特殊的正則表達式元字符。您得到的模式實際上是\.\*,並且由於您使用了需要完整字符串匹配的matches(),因此只能將.*字符串與它匹配(使用find()可以將其匹配到字符串中的任意位置)。

source code

public fun fromLiteral(literal: String): Regex = Regex(escape(literal))