字串操作(Manipulating Strings)
在 Octave 中有很多可以處理字串操作的函數,由於字串本身就是以矩陣的方式儲存,因此可以使用一般的運算子進行簡單的字串操作,下面的範例說明如何將字串中的空白字元替換成下底線:
quote = "First things first, but not necessarily in that order"; quote( quote == " " ) = "_"
輸出為
quote = First_things_first,_but_not_necessarily_in_that_order
對於較複雜的字串操作,例如搜尋、取代與常規表示法可以使用下面的函數:
deblank (s)
deblank(s) 函數會移除字串 s 結尾處的空白與 null 字元,若 s 為字元陣列,則會將每一列(row)結尾的共同空白移除,若 s 為字串的巢狀陣列,則 deblank() 函數會以遞迴的方式,將巢狀陣列中的每一個字串結尾處的空白都移除。例如:
s = "string "; s2 = deblank(s); whos s s2
輸出為
Attr Name Size Bytes Class
==== ==== ==== ===== =====
s 1x8 8 char
s2 1x6 6 char
字元陣列的範例:
m = ["ab "; "12345 "; "xyz "]; m2 = deblank(m); whos m m2
輸出為
Attr Name Size Bytes Class
==== ==== ==== ===== =====
m 3x7 21 char
m2 3x5 15 char
字元矩陣 m 是一個 3 乘 7 的矩陣,三個列的結尾都有共同的兩個空白字元,因此 deblank() 函數會移除每一列的最後兩個空白,最後得到的 m2 為 3 乘 5 的字元矩陣。
巢狀陣列的範例:
a = {"ABC ", "12 "};
b = deblank(a);
whos a{1} a{2} b{1} b{2}
輸出為
Attr Name Size Bytes Class
==== ==== ==== ===== =====
a{1} 1x5 5 char
a{2} 1x3 3 char
b{1} 1x3 3 char
b{2} 1x2 2 char
strtrim (s)
strtrim(s) 函數會移除字串 s 開頭與結尾處的空白與 null 字元,若 s 為字元矩陣,則會將每一列(row)開頭與結尾處的共同空白移除,若 s 為字串的巢狀陣列,則 strtrim() 函數會以遞迴的方式,將巢狀陣列中的每一個字串開頭與結尾處的空白都移除。例如:
strtrim (" abc ")
輸出為
ans = abc
strtrim ([" abc "; " def "])
輸出為
ans = abc def
strtrunc (s, n)
strtrunc(s, n) 函數會擷取字串 s 的開頭前 n 個字元,若 s 為字元矩陣,則擷取開頭的前 n 個行(column);若 s 為字串的巢狀陣列,則 strtrunc() 函數會擷取巢狀陣列中每一個自串的開頭前 n 個字元,並傳回新的巢狀陣列。
findstr (s, t, overlap)
findstr(s, t) 函數可搜尋 s 與 t 兩個字串之中較短的字串在較長字串中出現的位置,例如:
findstr ("ababab", "a")
輸出為
ans = 1 3 5
也可以寫成這樣
findstr ("a", "ababab")
輸出為
ans = 1 3 5
若將 overlap 參數設為 0,則輸出的位置就不會重複:
findstr ("abababa", "aba", 0)
輸出為
ans = 1 5
若不設定 overlap 參數,則預設會輸出重複的位置,例如:
findstr ("abababa", "aba")
輸出為
ans = 1 3 5
idx = strchr (str, chrs) idx = strchr (str, chrs, n) idx = strchr (str, chrs, n, direction)
strchr() 函數與 find() 函數類似,strchr(str, chars) 函數會搜尋字串 chars 中所指定的字元出現在字串 str 中的位置,例如:
strchr("abcd1234abcd", "b3")
輸出為
ans =
2 7 10
這會傳回字串 "abcd1234abcd" 中所有出現字元 "b" 或 "3" 的位置。
參數 n 是限制最多搜尋的個數,參數 direction 是尋找的方向,可以設定為 "first" (從開頭開始向後搜尋)或 "last"(從結尾開始像前搜尋),例如:
strchr("abcd1234abcd", "b3", 2, "last")
輸出為
ans =
7 10
strchr() 函數的搜尋速度在大部分的情況會比常規表示法函數快。index (s, t) index (s, t, direction)
index(s, t) 函數會傳回字串 s 中第一個出現字串 t 的位置,若字串 s 中沒有出現字串 t 則傳回 0,例如:
index ("Teststring", "t")
輸出為
ans = 4
參數 direction 是指定搜尋方向,若指定為 "first" 則傳回第一個出現的位置,若指定為 "last" 則傳回最後一個出現的位置。
index() 函數不適用於字串陣列或是字元矩陣。rindex (s, t)
rindex(s, t) 函數會傳回字串 s 中最後一個出現字串 t 的位置,若字串 s 中沒有出現字串 t 則傳回 0,此函數之功用等同於 index() 將 direction 參數設為 "last"。例如:
rindex ("Teststring", "t")
輸出為
ans = 6
rindex() 函數不適用於字串陣列或是字元矩陣。strfind (str, pattern) strfind (cellstr, pattern, direction)
strfind(str, pattern) 函數會搜尋 pattern 在字串 str 中出現的位置,若沒有出現或 pattern 的長度比 str 的長度長,則傳回空陣列 []。若 str 指定為字串的巢狀陣列,則傳回值為向量的巢狀陣列。例如:
strfind ("abababa", "aba")
輸出為
ans = 1 3 5
strfind ({"abababa", "bebebe", "ab"}, "aba")
輸出為
ans =
{
[1,1] =
1 3 5
[1,2] = [](1x0)
[1,3] = [](1x0)
}
strmatch (s, a, "exact")
strmatch(s, a) 函數傳回在 a 中出現字串 s 的元素索引,其傳回值是一個行向量,參數 a 為字元矩陣或字串的巢狀陣列。若沒有設定 "exact" 參數,則只比對開頭是否與 s 相同。null 字元會比對空白字元。例如:
strmatch ("apple", "apple juice")
輸出為
ans = 1
strmatch ("apple", ["apple pie"; "apple juice"; "an apple"])
輸出為
ans = 1 2
strmatch ("apple", {"apple pie"; "apple juice"; "tomato"})
輸出為
ans = 1 2
[tok, rem] = strtok (str, delim)
strtok(str, delim) 函數會找出 delim 之中的字元在字串 str 中第一個出現的位置,並將此字元之前的字串傳回(不包含此字元),若是有設定輸出參數 rem,則 rem 中會包含此字元之後的字串(包含此字元)。若是字串的第一個字元就在 delim 之中,則第一個字元會被忽略。若不指定 delim 則預設為空白字元。例如:
strtok ("this is the life")
輸出為
ans = this
[tok, rem] = strtok ("14*27+31", "+-*/")
輸出為
tok = 14 rem = *27+31
[s] = strsplit (p, sep, strip_empty)
strsplit(p, sep, strip_empty) 函數會以 sep 中的字元做為分隔字元,將字串 p 切成字串的巢狀陣列,字串 p 中若包含連續或位於字串兩端的分隔字元會使結果中產生空字串,若要將空字串移除,可指定 strip_empty 參數為 true,若不指定預設為 false。例如:
strsplit("this is the life", " ")
輸出為
ans =
{
[1,1] = this
[1,2] = is
[1,3] = the
[1,4] = life
}
strrep (s, x, y)
strrep(s, x, y) 函數會將字串 s 中所有出現字串 x 的地方都替換成字串 y,並傳回替換後的結過,例如:
strrep ("This is a test string", "is", "&%$")
輸出為
ans = Th&%$ &%$ a test string
substr (s, offset, len)
substr(s, offset, len) 函數傳回 s 字串的子字串,此子字串從 s 字串的第 offset 字元開始往後算起,長度為 len。若 offset 指定為負數,則開始的位置變成從 s 字串的結尾往前算。若不指定 len 參數,則傳回的子字串會取至 s 字串的結尾。例如:
substr ("This is a test string", 6, 9)
輸出為
ans = is a test
[s, e, te, m, t, nm] = regexp (str, pat) [...] = regexp (str, pat, opts, ...)
regexp() 函數使用常規表示法(regular expression)進行字串的比對,在字串 str 中比對由 pat 所指定的常規表示法,並傳回符合的字串及其位置,若是找不到符合的字串則傳回空向量,pat 中可以使用任何標準的常規表示法,包含:
.:比對任意字元。* + ? {}重複運算子(Repetition operators):*:比對 0 次以上。+:比對 1 次以上。?:比對 0 次或 1 次。{}:指定比對的次數,{n}為剛好比對n次,{m,}為比對m次以上,{m,n}為比對m次到n次。
[...] [^...]:列舉運算子(List operators),例如[ab]c為比對ac或bc。():群組運算子(Grouping operator)。|:多重選擇運算子(Alternation operator),比對其中一種常規表示法,此運算子必須配合上述的群組運算子使用。^ $:定位運算子(Anchoring operator),^比對字串str的開頭,$比對字串str的結尾。
下列的跳脫字元(escaped character)表示各種特殊意義,在使用這些跳脫字元時,建議使用單引號將常規表示法 pat 包起來,而不要使用雙引號,這樣可以避免這些跳說字元在傳給 regexp() 函數時就被 Octave 解析成其他的字元。
\b:比對字(word)的邊界。\B:比對除了字邊界以外的地方。\w:比對英文字字元。\W:比對\w以外的字元。\<:比對字(word)的開頭。\>:比對字(word)的結尾。\s:比對空白、Tab 等字元。\S:比對\s以外的字元。\d:比對數字。\D:比對\d以外的字元。
regexp() 函數的傳回值預設是依照下面的順序傳回:
s:每一個符合的子字串起始索引值。e:每一個符合的子字串結尾索引值。te:包含所有在pat中被群組運算子()包起來的區段索引。m:一個巢狀陣列,包含所有比對符合的內容。t:一個巢狀陣列,包含所有在pat中被群組運算子()包起來的區段內容。nm:一個資料結構(structure),包含所有被具名的群組運算子()包起來的區段內容,一個名稱為name的群組運算子為(?...)。
regexp() 函數的傳回值格式可以藉由 opts 參數設定,可以指定傳回值與傳回的順序,可以用的選項有:
'start':指定s。'end':指定e。'tokenExtents':指定te。'match':指定m。'token':指定t。'names':指定nm。
regexp() 函數還有一些額外的參數:
'once':只傳回第一個比對成功的結果。'matchcase':將英文大小寫視為不同。'ignorecase':將英文大小寫視為相同。'stringanchors':設定定位運算子比對整個字串的開頭與結尾。'lineanchors':設定定位運算子比對行(line)的開頭與結尾。'dotall':設定句點.可比對任意字元,包含換行字元。'dotexceptnewline':設定句點.可比對除了換行字元之外的任意字元。'freespacing':將pat中#符號之後的所有內容或空白視為註解。'literalspacing':將在pat中的所有#符號視為一般字元來比對。
[s, e, te, m, t, nm] = regexpi (str, pat) [...] = regexpi (str, pat, opts, ...)
regexpi() 函數與 regexp() 函數類似,但此函數將英文大小寫視為相同。
string = regexprep (str, pattern, repstr, options)
regexprep(str, pattern, repstr, options) 函數會以常規表示法 pattern 比對字串 str,並將比對符合的部分以 repstr 取代。repstr 中亦可以使用 $i 表示在 pattern 中第 i 個以括弧包起來的部分,例如:
regexprep("Bill Dunn", '(\w+) (\w+)', '$2, $1')
輸出為
ans = Dunn, Bill
參數 options 部分可以使用的有:
'once':只替換第一個比對成功的結果。'warnings':這個參數是為了相容性而設置的,並沒有作用。'ignorecase'與'matchcase':設定是否將英文大小寫視為相同,亦可在pattern中以(?i)與(?-i)指定。'lineanchors'與'stringanchors':設定定位運算子比對行(line)的開頭與結尾,或是比對整個字串的開頭與結尾,亦可在pattern中以(?m)與(?-m)指定。'dotexceptnewline'與'dotall':設定句點 . 是否比對換行字元,亦可在pattern中以(?s)與(?-s)指定。'freespacing'與'literalspacing':設定#與空白是否可用於pattern中做為註解,亦可在pattern中以(?x)與(?-x)指定。
例如:
regexprep("ABC\nabc\nAbc", "^ab", "XY", 'ignorecase', 'lineanchors')
輸出為
ans = XYC XYc XYc
regexptranslate (op, s)
regexptranslate(op, s) 函數會將字串 s 轉換為常規表示法中使用的格式,參數 op 是指定轉換的類型,可用的選項有:
"wildcard":將 wildcard 字元轉換為常規表示法,例如*與?等。"escape":將跳脫字元轉換為常規表示法,例如$ . ? []等。
下面是一些範例:
regexptranslate ("wildcard", "*.m")
輸出為
ans = .*\.m
regexptranslate ("escape", "12.5")
輸出為
ans = 12\.5