在Groovy中使用字符串
Groovy支持兩種類型字符串:一般的Java字符串,它是java.lang.String的實例;和GStrings,它是groovy.lang.GString的實例,并且允許文本中包含占位符。GStrings并不是String的子類,因為String類是最終類(final class)不能被繼承。然而,GString與一般的字符串一樣,因為Groovy能將GStrings轉型為Java strings。
GString 適用于編寫模板代碼(templating),因為您必須動態(tài)構建字符串(GStrings are useful in templating situations where you have to build your string dynamicly)。以下的清單給出了一個例子。
使用GStrings:
- firstWord = 'Hello'
- secondWord = 'dlroW'
- println "$firstWord ${secondWord.reverse()}"
結果如下:
- Hello World
GStrings不同于Java strings在于它們允許以${..}的語法嵌入變量。如果一個字符串由雙引號或三重引號括起來,并且包含一個非轉義符(unescaped)$,它必定是groovy.lang.GString的一個實例;否則,就是java.lang.String的一個實例。
${..}里可以包含任意有效的Groovy表達式,包括方法調用或變量名。只有調用GString的toString方法時(例如,把結果輸出到控制臺),${..}表達式才被求值。
Groovy支持的另一種字符串便是java.lang.String。然而,GDK還是動態(tài)注入許多幫助方法,使其易于應用。
以下的例子展示了在Groovy中聲明一個字符串的不同方式:
- s1 = "Hello \"World\" " //Escape double quotes,轉義雙引號
- s2 = 'Hello "World" '
- assert s1 == s2
- s3 = 'Hello \'World\' ' //Escape single quotes,轉義單引號
- s4 = "Hello 'World' "
- assert s3 == s4
- assert new String('Hello World') == "Hello World"
- def s = ['h','e','l','l','o'] as char[]
- assert new String(s) == 'hello'
- assert new String(s,0,4) == 'hell'
- s.eachWithIndex{ch,index -> assert ch == s[index]}
- assert 'hello'.toCharArray() == ['h','e','l','l','o']
常用的轉義符:
- assert '\t' == '\011' //Tab,Tab鍵
- assert '\n' == '\012' //New line,換行符
- assert '\r' == '\015' //Carriage return,回車
- assert '\n' == """
- """ //Spanning multiple lines,跨越多行
對象的字符串表示:
- def object = new Object()
- assert String.valueOf(object) == object.toString() //Objects
- assert String.valueOf(true) == true.toString() //Booleans
- assert String.valueOf('a') == 'a'.toString() //Characters
- assert String.valueOf(1) == 1.toString() //Numbers
- assert String.valueOf([a:1,b:2]) == [a:1,b:2].toString() //Collections
字符串長度:
- s = "Hello World"
- assert s.size() == 11
- assert s.size() == s.length()
填充(pad)字符串:
- assert 'Hello'.padRight(7,'*') == 'Hello**'
- assert 'Hello'.padLeft(7,'*') == '**Hello'
- assert 'Hello'.center(9,'*') == '**Hello**'
分解字符串:
- s = "The quick brown fox jumps over the lazy dog"
- assert s.tokenize() == ['The','quick','brown','fox','jumps','over','the','lazy','dog']
- assert s.tokenize() == new StringTokenizer(s).collect{it}
- s1 = "The,quick*brown*fox,*jumps*over*the*lazy*dog"
- assert s1.tokenize(',*') == s.tokenize()
查詢字符串:
- alphabets = new String('a' .. 'z' as char[])
- assert alphabets.find{it > 'f'} == 'g' //First one found
- assert alphabets.findAll{it > 'f'} == 'g' .. 'z'//ALl found
- assert alphabets.findIndexOf{ it > 'f'} == alphabets.indexOf('g')
- assert alphabets.every {it > 'A'}
- assert alphabets.any{it < 'c'}
- assert alphabets.startsWith('abc')
- assert alphabets.endsWith('xyz')
- assert alphabets.contains('def')
- assert alphabets.indexOf('c') == 2
- assert alphabets.indexOf('d') == alphabets.lastIndexOf('d')
- assert alphabets.count('a') == 1
替換字符串:
- s = "Hello"
- assert s.replace('H','Y') == 'Yello'
- assert s.replace('l','p') == 'Heppo'
字符串反轉:
- s = 'mirror'
- assert s.reverse() == 'rorrim'
字符串操作符:
- assert 'hello' + ' world' - 'l' == 'helo world' //Subtracts at most one l
- assert ('Today is Sunday' - 'Sunday').trim() == 'Today is'
- assert 'hello ' * 2 == 'hello hello '
- def empty = []
- assert 'abc'.each{empty << it} == 'abc'
- assert 'abc'.next() == 'abd'
- assert 'abc'.previous() == 'abb'
下標操作符:
- assert 'hello'[1] == 'e'
- assert 'hello'[2..'hello'.size() - 1] == 'llo'
- assert 'hello'[0,2,4] == 'hlo'
- assert 'hello'[-4,-2] == 'el'
字符串比較:
- assert 'a' < 'b'
- assert 'a' > 'A'
- assert 'a'.compareTo('b') == -1
- assert 'a'.compareToIgnoreCase('A') == 0
尋找最大值和最小值:
- Collections.max('abcdeF'.toList()) == 'e'
- assert Collections.max('abcdeF'.toList(), String.CASE_INSENSITIVE_ORDER) == 'F'
- assert Collections.min(['abc','abd','abe']) == 'abc'
- assert Collections.min(['Abc','aBd','abE'], String.CASE_INSENSITIVE_ORDER) == 'Abc'
StringBuffers和StringBuilders是可變的,允許字符串改變。StringBuilder不是線程安全的,因此處理速度要比StringBuffers快。
- def sb = new StringBuffer('Hello World')
- assert sb.toString() == 'Hello World'
- sb.length = 5
- assert sb.toString() == 'Hello'
- assert sb.substring(0,2) == 'He'
- //Use <<, append(String) or leftShift(String) to append to a StringBuffer.
- //Using + to append to a StringBuffer will return a String
- sb = new StringBuffer("Hello")
- assert sb + ' World' in java.lang.String
- assert sb << ' World' in java.lang.StringBuffer
- assert sb.toString() == ("Hello World")
- assert sb.append(", Groovy rocks").toString() == "Hello World, Groovy rocks"
- assert sb.leftShift(". Doesn't?").toString() == "Hello World, Groovy rocks. Doesn't?"
您也可以對StringBuffer或StringBuilder使用下標,如:
- sb = new StringBuffer("abcdefg")
- assert sb[0] == 'a'
- assert sb[2..4] == 'cde'
- assert sb[0].class == String
- assert sb[-6..-4] == "bcd"
- sb[0..2] = "xyz"
- assert sb.toString() == "xyzdefg"
操作StringBuffers:
- sb = new StringBuffer("StringBuffers are mutable")
- sb.delete(sb.indexOf(" are mutable"),sb.size())
- assert sb.toString() == "StringBuffers"
- sb.insert(sb.size(), " are mutable")
- assert sb.toString() == "StringBuffers are mutable"
- sb.replace(sb.indexOf("StringBuffers"), "StringBuffers".size(), "StringBuilders")
- assert sb.toString() == "StringBuilders are mutable"
- def string = new String(sb)
- def string2 = string.replaceAll("StringBuilders", "StringBuffers")
- assert string2 == "StringBuffers are mutable"
正如您看到的,GDK在java.lang.String,java.lang.StringBuffer和java.lang.StringBuilder基礎上添加了很多實用的方法。前面的例子只討論部分方法,因此推薦您查看String的API文檔,http://groovy.codehaus.org/groovy-jdk/java/lang/String.html;StringBuffer, http://groovy.codehaus.org/groovy-jdk/java/lang/StringBuffer.html; StringBuilder, http://groovy.codehaus.org/groovy-jdk/java/lang/StringBuilder.html。
在Groovy中使用字符串時,需要注意以下幾點:
與Java一樣,Groovy中的字符串也是不可變的(即只讀的)。欲改變字符串值需使用StringBuffer或StringBuilder。
Groovy中,如果字符串如果由單引號括起來,或者由雙引號或三重引號括起來但沒有非轉義的美元符號($),那么該字符串是java.lang.String的一個實例。您可使用JDK中任意字符串方法。另外,GDK動態(tài)注入額外的實用方法到String類。
由于Groovy會自動轉型為String類,您可以在任何時候使用GStrings。
字符串可被單引號,雙引號或者三重引號括起來。其中,三重引號可直接跨越數行并且輸出中仍包含回車符、制表符和空格符。
Groovy使用size方法來查詢一個字符串,StringBuffer或StringBuilder的長度,與查詢一個集合的長度相統(tǒng)一。
某些字符串方法接受閉包,它明確說明需要滿足的條件,例如,find,findAll,findIndexOf,every和any。這些方法都是由GDK動態(tài)注入到java.lang.Object中的。
您可以使用collect,each或者eachWithIndex方法遍歷字符串,而且這些方法也屬于java.lang.Object的一部分。
您可對字符串使用操作符。操作符“+”完成字符串聯(lián)接;“-”則最多去掉一個右操作數的實例;“*”按照給定的數字復制字符串;next實現字符串最后一個字節(jié)自增;previous實現字符串最后一個字節(jié)自減。
您可對Strings,StringBuffers和StringBuilders使用下標操作符,也可以在下標操作符中使用range和負索引(即索引可以是負數,計數從右邊開始)。
【編輯推薦】