Octave で文字列操作
Octave での文字列は,1 文字を要素とする配列なので,ベクトルや行列と同じように扱うことができる。
1. 特別な関数を使わない文字列操作
1.1. 配列の参照 ( )
s = "set the character used to separate the filename."
s(2:6), s(7), s(end)
s = set the character used to separate the filename.
ans = et th
ans = e
ans = .
1.2. 文字列の逆転 (end:-1:1)
, flip()
配列の参照法の応用で文字列を逆転することができる。関数としては flip()
がある。
s = "abcdefghij"
s(end:-1:1)
flip(s)
s = abcdefghij
ans = jihgfedcba
ans = jihgfedcba
1.3. 文字列のスライス (1:step:end)
配列の参照法そのままであるが,一定間隔で文字を取り出すことができる。
s = "abcdefghij"
s(1:3:end)
s = abcdefghij
ans = adgj
1.4. 文字列と文字列行列 [ ]
以下は 3 個の文字列を要素として持つ行ベクトルを定義しているつもりであるが,これは一つの文字列になる。
["a", "bc", "def"]
ans = abcdef
要素の区切り文字として ;
が使われると文字行列になる。
["a"; "bc"; "def"]
ans =
a
bc
def
1.5. 次元の変更 reshape()
配列操作は,要素が数値の場合と同じように実行される。
a = reshape(s, 12, 4)'
error: reshape: can't reshape 1x10 array to 12x4 array
a(2, 7), a(3, :)
error: 'a' undefined near line 1, column 1
1.6. 比較演算子 ==
, !=
, <
, <=
, >
, >=
演算子 ==
も,それぞれの要素に対して作用する。以下の例では文字が空白なら 1(true),そうでないなら 0(false) を返す。
spaces = "foo bar baz" == " "
spaces =
0 0 0 1 0 0 0 1 0 0 0
2. 文字列中の文字
2.1. 文字の出現位置 strchr()
検索する文字は複数個指定できる(1 つの文字列として指定する)。
strchr("abcdefg 12345 #$%4", "d2#")
ans =
4 10 15
検索する個数を指定できる。
strchr("abcdefg 12345 #$%4", "d2#", 2)
ans =
4 10
後ろから検索する場合は "last"
を指定する("first"
がデフォルト)。このとき,検索する個数は必ず指定しなければならない。すべてを検索したいが個数がわからないというときには大きな数を指定しておけばよい。
strchr("abcdefg 12345 #$%4", "d2#", 2, "last")
ans =
10 15
戻り値は検索された文字の出現位置である。
s = ["abcdefg"; "12345"; "#$%4"]
[i, j] = strchr(s, "d2#")
s =
abcdefg
12345
#$%4
i =
3
2
1
j =
1
2
4
2.2. 文字列中の 1 文字を全置換
s = "set the character used to separate the filename.";
s(s == " ") = "*"; # インプレースで置換される
s
s = set*the*character*used*to*separate*the*filename.
2.3. タブを空白で置き換える untabify(s, tabstop, deblank)
tabstop はデフォルトで 8。deblank が true なら末尾の空白を除去する。
s = "abc\tdef\t"
printf("'%s'\n", untabify(s))
printf("'%s'\n", untabify(s, 4))
printf("'%s'\n", untabify(s, 4, true))
s = abc def
'abc def '
'abc def '
'abc def'
3. 文字列の置換
3.1. 文字列中の部分文字列を全置換 strrep()
strrep("This is a test string", "is", "***")
ans = Th*** *** a test string
3.2. 文字列中の部分文字列を全削除 erase()
erase("This is a test string", "is")
ans = Th a test string
erase("abababa", "aba") # overlap = true
ans = b
4. 部分文字列
4.1. 部分文字列を取り出す substr()
第 2 引数で指定した文字位置以降最後尾までの文字列を返す。
substr("123456789", 4)
ans = 456789
第 2 引数が負の場合は最後から文字列を取り出す。
substr("123456789", -4)
ans = 6789
第 3 引数は取り出す文字列を示す。
substr("123456789", 4, 3)
ans = 456
第 3 引数が負の場合は,最後からの文字数まで取り出す。
substr("123456789", 4, -2)
ans = 4567
substr("123456789", -4, -2)
ans = 67
4.2. 部分文字列検索 index()
, rindex()
部分文字列が見つかった場合はその位置を返す。見つからなかった場合は 0 を返す。
index("abcdefghijdexxxde", "de")
index("abcdefghijdexxxde", "dx")
ans = 4
ans = 0
最後に見つかったものを検索する場合は "last"
を指定する(デフォルトは "first"
)。
index("abcdefghijdexxxde", "de", "first")
index("abcdefghijdexxxde", "de", "last")
ans = 4
ans = 16
rindex(s, t)
は index(s, t, "last")
と同じである。
index("abcdefghijdexxxde", "de", "last")
rindex("abcdefghijdexxxde", "de")
index("abcdefghijdexxxde", "dx")
rindex("abcdefghijdexxxde", "dx")
ans = 16
ans = 16
ans = 0
ans = 0
4.3. 部分文字列の開始位置 strfind()
index()
は,最初か最後の 1 つだけを検索するが,strfind()
はすべての開始位置を検索する。
strfind("set the character used to separate the filename", "the")
ans =
5 36
strfind("set the character used to separate the filename", "xxx")
ans = [](0x0)
strfind("abababa", "aba", "overlaps", false) # オーバーラップを許さない
ans =
1 5
strfind("abababa", "aba") # オーバーラップを許す(デフォルト)
ans =
1 3 5
5. 文字列の比較
長さが同じ文字列に対して ==
を使うと,それぞれの文字位置で同じかどうかの結果を返す。文字列の長さが異なる場合はエラーになる。
"abc" == "abc"
ans =
1 1 1
5.1. 文字列が同じかどうか strcmp()
文字列として同じかどうかは strcmp()
を使わなければならない。
strcmp("abc", "abc")
ans = 1
5.2. 最初の数文字が同じかどうか strncmp()
最初の数文字だけが同じかどうかは strncmp()
を使う。
strncmp("abcde", "abcxy", 3), strncmp("abcde", "abcxy", 4)
ans = 1
ans = 0
2 つの引数のいずれかが文字列を要素とするセル配列の場合は,比較結果はセル配列の要素数のベクトルになる。
strncmp ("abce", {"abcd", "bca", "abc"}, 3)
ans =
1 0 1
5.3. 大文字・小文字を無視して比較する strcmpi()
アルファベットの大文字・小文字の区別をしない比較は strcmpi()
を使う。
strcmpi("ABCde", "aBcDe")
ans = 1
5.4. 大文字・小文字を無視して数文字だけ比較する strncmpi()
アルファベットの大文字・小文字の区別をしないで最初の数文字だけで比較する場合は strncmpi()
を使う。
strncmpi("ABCde00", "aBcDe99", 5)
ans = 1
6. 文字列を取り出すstrtok()
先頭から区切り文字の前までの文字列を取り出す。区切り文字は複数指定可能(デフォルトでは空白)。
strtok("abc def ghi")
ans = abc
strtok("abc def ghi", "f")
ans = abc de
戻り値を指定することにより,取り出された文字列と残りの文字列を得ることができる。
[token, remind] = strtok ("14*27+31", "+-*/")
token = 14
remind = *27+31
7. 文字列の分割
7.1. 文字列分割 strsplit()
デリミター 1 文字(デフォルトでは空白)で文字列を分割する。
複数のデリミターを指定するときは,次項のostrsplit()
を使用するか,正規表現を使い "delimitertype", "regularexpression"
とする。
strsplit("foo bar baz")
ans =
{
[1,1] = foo
[1,2] = bar
[1,3] = baz
}
strsplit("foo bar baz", " ")
ans =
{
[1,1] = foo
[1,2] = bar
[1,3] = baz
}
戻り値を指定することにより,取り出された文字列とマッチした文字列を得ることができる。
[word, matches] = strsplit("foo@bar@baz", "@")
word =
{
[1,1] = foo
[1,2] = bar
[1,3] = baz
}
matches =
{
[1,1] = @
[1,2] = @
}
[word, matches] = strsplit ("a foo b,bar c", ',|\s|foo|bar',
"delimitertype", "regularexpression")
word =
{
[1,1] = a
[1,2] = b
[1,3] = c
}
matches =
{
[1,1] = foo
[1,2] = ,bar
}
7.2. 複数のデリミターで文字列を分割 ostrsplit()
ostrsplit("foo@bar,baz", "@,")
ans =
{
[1,1] = foo
[1,2] = bar
[1,3] = baz
}
8. 文字列連結 strcat()
, strvcat()
, char()
文字列を連結して 1 つの文字列にする。
strcat()
は横方向に連結する。[文字列1, 文字列2, ...]
と同じ結果になる。
strcat("aaa", "999", "#$%")
ans = aaa999#$%
strvcat()
は縦方向に連結する。つまり,複数の文字列ベクトルになる。[文字列1; 文字列2; ...]
と同じ結果になる。
a = strvcat("aaa", "999", "#$%")
a =
aaa
999
#$%
char()
は引数の指定法により strcat()
, strvcat()
と同じ結果を生み出す。
char("aaa", "999", "#$%")
ans =
aaa
999
#$%
char(["aaa"; "999"; "#$%"])
ans =
aaa
999
#$%
char(["aaa", "999", "#$%"])
ans = aaa999#$%
char([98, 97, 110, 97, 110, 97])
ans = banana
9. 文字配列の結合 strjoin()
セル文字列を結合して 1 つの文字列にする。
strjoin({"i", "have", "a", "pen"})
ans = i have a pen
結合するときのデリミターを指定することができる(デフォルトでは 1 個の空白)。
strjoin({"i", "have", "a", "pen"}, delimiter=""), ["i", "have", "a", "pen"]
ans = ihaveapen
ans = ihaveapen
strjoin({"i", "have", "a", "pen"}, delimiter=":")
ans = i:have:a:pen
strjoin({"i", "have", "a", "pen"}, delimiter="---")
ans = i---have---a---pen
10. 小文字に変換 tolower()
, lower()
tolower("ABCDE123"), lower("ABCDE123")
ans = abcde123
ans = abcde123
11. 大文字に変換 toupper()
, upper()
toupper("abcde123"), upper("abcde123")
ans = ABCDE123
ans = ABCDE123
12. 数値と文字の相互変換
12.1. 数値を文字に変換 char()
char(0x61)
ans = a
char(97:122)
char([98, 97, 110, 97, 110, 97])
ans = abcdefghijklmnopqrstuvwxyz
ans = banana
char([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
ans =
abc
98
99
d
str1
half
12.2. 文字を数値に変換 int**()
int8("x")
int32(["a", "b"]) # ["a", "b"] ==> "ab"
int64("character")
ans = 120
ans =
97 98
ans =
99 104 97 114 97 99 116 101 114
13. 数値と文字列の相互変換
13.1. 数値を文字列に変換する
13.1.1. num2str()
num2str(int32(123)), num2str(123.0), num2str(123.456)
ans = 123
ans = 123
ans = 123.456
13.1.2. disp()
disp()
を使う場合,文字列の最後に改行記号(LF)がつく。
a = disp(123.456)
class(a), typeinfo(a)
a = 123.46
ans = char
ans = sq_string
printf("**%s**", a)
**123.46
**
int32(a(end)) # 0xa; LF(line feed)
ans = 10
改行記号を取り除くためには deblank()
を使えばよい。
b = deblank(disp(123.456))
b = 123.46
printf("**%s**", b)
**123.46**
13.1.3. sprintf()
sprintf()
を使えば,任意の形式で文字列に変換できる。
b = sprintf("%g", 123.456)
class(b), typeinfo(b)
b = 123.456
ans = char
ans = string
printf("**%s**", b)
**123.456**
13.2. 文字列を数値に変換する
13.2.1. str2num()
"123, 456.789"
は 2 つの数値に変換される。
format long
str2num("123.456"), str2num("123, 456.789"), str2num(["1" "2" "3"; "4" "5" "6"])
ans = 123.4560000000000
ans =
123.0000000000000 456.7890000000000
ans =
123
456
13.2.2. str2double()
"123, 456.789"
は数値構成要素以外の ,
を含むため NaN
になる。
str2double("123.456"), str2double("123, 456.789"), str2double(["1" "2" "3"; "4" "5" "6"])
ans = 123.4560000000000
ans = NaN
ans =
123
456
13.2.3. eval()
eval("123.456")
ans = 123.4560000000000
14. 空白の除去
14.1. 末尾の空白類と NULL の除去 deblank()
printf("'%s'\n", deblank(" abcdef "))
' abcdef'
引数が文字行列の場合は,各行の長い方に合わせて空白が除去される。
s = deblank([" foo678 "
" bar123 "]);
printf("'%s'\n'%s'\n", s(1, :), s(2, :))
' foo678 '
' bar123'
引数がセル配列の場合は,各要素について再帰的に空白が除去される。
deblank({" abc ", {" def ", " uvxyz"}})
ans =
{
[1,1] = abc
[1,2] =
{
[1,1] = def
[1,2] = uvxyz
}
}
14.2. 先頭と末尾の空白の除去 strtrim()
printf("'%s'\n", strtrim(" abcdef "))
'abcdef'
引数が文字行列の場合は,各行の長い方に合わせて空白が除去される。
s = strtrim([" foo678 "
" bar123 "]);
printf("'%s'\n'%s'\n", s(1, :), s(2, :))
'foo678 '
' bar123'
引数がセル配列の場合は,各要素について再帰的に空白が除去される。
strtrim({" abc ", {" def ", " uvxyz"}})
ans =
{
[1,1] = abc
[1,2] =
{
[1,1] = def
[1,2] = uvxyz
}
}
15. 文字列の切り詰め strtrunc()
strtrunc("abcdefghij", 5)
ans = abcde
文字行列の場合は,各行に対して文字列が切り詰められる。
strtrunc(["abcdefghij"; "0123"; "qwertyuiop"; "!@#$%^&*()"], 5)
ans =
abcde
0123
qwert
!@#$%
セル配列の場合,セルはネストしてはいけない。
strtrunc({"abc", "def9", "uvxyz"}, 2)
ans =
{
[1,1] = ab
[1,2] = de
[1,3] = uv
}
16. 任意の長さの空白文字列 blanks()
printf("+++++%s*****\n", blanks(5))
+++++ *****
17. 文字列の空白パディング strjust()
s = ["a"; "foo"; "super"];
17.1. 左揃え
strjust(s, "left")
ans =
a
foo
super
17.2. 中央揃え
strjust(s, "center")
ans =
a
foo
super
17.3. 右揃え
strjust(s, "right")
ans =
a
foo
super
18. ダブルクオートで囲まれた文字列か? is_dq_string()
ダブルクオートで囲まれた文字列のとき true
を返す。
is_dq_string("abc"), is_dq_string('abc')
ans = 1
ans = 0
19. シングルクオートで囲まれた文字列か? is_sq_string()
シングルクオートで囲まれた文字列のとき true
を返す。
is_sq_string("abc"), is_sq_string('abc')
ans = 0
ans = 1
class("abc"), class('abc')
ans = char
ans = char
20. 文字配列か? ischar()
x
が文字配列(スカラーの場合も含む)のとき true
を返す。
ischar('xy'), ischar("bcd"), ischar(["a", "b", "x"]), ischar([9, 8])
ans = 1
ans = 1
ans = 1
ans = 0
21. 文字種
文字の種類を判定する。
21.1. アスキー文字か? isascii()
isascii(['a', '1', '#'])
ans =
1 1 1
isascii(['a', '1', char(230)])
ans =
1 1 0
21.2. 制御文字か? iscntrl()
iscntrl(['a', '1', "\n"])
ans =
0 0 1
21.3. 10 進数字か? isdigit()
isdigit(['a', '1', "\n"])
ans =
0 1 0
21.4. 16 進数字か? iaxdigit()
isxdigit(['a', '1', 'F', 'x'])
ans =
1 1 1 0
21.5. 小文字か? islower()
islower(['a', 'A'])
ans =
1 0
21.6. 大文字か? isupper()
isupper(['a', 'A'])
ans =
0 1
21.7. プリントできるか?
21.7.1. 空白を含む isprint()
isprint([" ", "1", "a"])
ans =
1 1 1
21.7.2. 空白は含まない isgraph()
isgraph([" ", "1", "a"])
ans =
0 1 1
21.8. 区切り文字か? ispunct()
ispunct([",", ":", ";", "-", "\n"])
ans =
1 1 1 1 0
21.9. 空白類か? isspace()
isspace([" ", "\t", "\f", "\r", "\n"])
ans =
1 1 1 1 1
22. 文字列を評価する eval()
, evalc()
eval("x = sqrt(8)")
x = 2.828427124746190
第 1 引数の評価が失敗すると,第 2 引数が評価される。
eval("sqrt()", "99999")
ans = 99999
評価した結果を文字列で返す。
s = evalc("x = sqrt(8)");
s
x
s = x = 2.828427124746190
x = 2.828427124746190
23. 問題1
任意の文字を任意個数繰り返す文字列,たとえば "@@@@@"
を作るにはどうすればよいか。
repelem("@", 5)' # 最後の ' が必須
ans = @@@@@
24. 問題2
任意の文字列を任意組数繰り返す文字列,たとえば "@*#@*#@*#@*#"
を作るにはどうすればよいか。
reshape(reshape(repelem("@*#", 4), 4, 3)', 1, 12)
ans = @*#@*#@*#@*#
reshape(reshape(repelem("@*#", 4), 4, [])', 1, []) # 要素数の指定を省略できる
ans = @*#@*#@*#@*#