Octave で文字列操作

# Octave で文字列操作

Octave での文字列は，1 文字を要素とする配列なので，ベクトルや行列と同じように扱うことができる。

## 1.　特別な関数を使わない文字列操作

### 1.1.　配列の参照 `( )`


```matlab
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()` がある。


```matlab
s = "abcdefghij"
s(end:-1:1)
flip(s)
```

    s = abcdefghij
    ans = jihgfedcba
    ans = jihgfedcba


### 1.3.　文字列のスライス `(1:step:end)`

配列の参照法そのままであるが，一定間隔で文字を取り出すことができる。


```matlab
s = "abcdefghij"
s(1:3:end)
```

    s = abcdefghij
    ans = adgj


### 1.4.　文字列と文字列行列 `[ ]`

以下は 3 個の文字列を要素として持つ行ベクトルを定義しているつもりであるが，これは一つの文字列になる。


```matlab
["a", "bc", "def"]
```

    ans = abcdef


要素の区切り文字として `;` が使われると文字行列になる。


```matlab
["a"; "bc"; "def"]
```

    ans =
    
    a  
    bc 
    def
    


### 1.5.　次元の変更 `reshape()`

配列操作は，要素が数値の場合と同じように実行される。


```matlab
a = reshape(s, 12, 4)'
```

    error: reshape: can't reshape 1x10 array to 12x4 array



```matlab
a(2, 7), a(3, :)
```

    error: 'a' undefined near line 1, column 1


### 1.6.　比較演算子 `==`, `!=`, `<`, `<=`, `>`, `>=`

演算子 `==` も，それぞれの要素に対して作用する。以下の例では文字が空白なら 1(true)，そうでないなら 0(false) を返す。


```matlab
spaces = "foo bar baz" == " "
```

    spaces =
    
      0  0  0  1  0  0  0  1  0  0  0
    


## 2.　文字列中の文字

### 2.1.　文字の出現位置 `strchr（）`

検索する文字は複数個指定できる（1 つの文字列として指定する）。


```matlab
strchr("abcdefg 12345 #$%4", "d2#")
```

    ans =
    
        4   10   15
    


検索する個数を指定できる。


```matlab
strchr("abcdefg 12345 #$%4", "d2#", 2)
```

    ans =
    
        4   10
    


後ろから検索する場合は `"last"` を指定する（`"first"` がデフォルト）。このとき，検索する個数は必ず指定しなければならない。すべてを検索したいが個数がわからないというときには大きな数を指定しておけばよい。


```matlab
strchr("abcdefg 12345 #$%4", "d2#", 2, "last")
```

    ans =
    
       10   15
    


戻り値は検索された文字の出現位置である。


```matlab
s = ["abcdefg"; "12345"; "#$%4"]
[i, j] = strchr(s, "d2#")
```

    s =
    
    abcdefg
    12345  
    #$%4   
    
    i =
    
       3
       2
       1
    
    j =
    
       1
       2
       4
    


### 2.2.　文字列中の 1 文字を全置換


```matlab
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 なら末尾の空白を除去する。


```matlab
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()`


```matlab
strrep("This is a test string", "is", "***")
```

    ans = Th*** *** a test string


### 3.2.　文字列中の部分文字列を全削除 `erase()`


```matlab
erase("This is a test string", "is")
```

    ans = Th  a test string



```matlab
erase("abababa", "aba") # overlap = true
```

    ans = b


## 4.　部分文字列

### 4.1.　部分文字列を取り出す `substr()`

第 2 引数で指定した文字位置以降最後尾までの文字列を返す。


```matlab
substr("123456789", 4)
```

    ans = 456789


第 2 引数が負の場合は最後から文字列を取り出す。


```matlab
substr("123456789", -4)
```

    ans = 6789


第 3 引数は取り出す文字列を示す。


```matlab
substr("123456789", 4, 3)
```

    ans = 456


第 3 引数が負の場合は，最後からの文字数まで取り出す。


```matlab
substr("123456789", 4, -2)
```

    ans = 4567



```matlab
substr("123456789", -4, -2)
```

    ans = 67


### 4.2.　部分文字列検索 `index()`, `rindex()`

部分文字列が見つかった場合はその位置を返す。見つからなかった場合は 0 を返す。


```matlab
index("abcdefghijdexxxde", "de")
index("abcdefghijdexxxde", "dx")
```

    ans = 4
    ans = 0


最後に見つかったものを検索する場合は `"last"` を指定する（デフォルトは `"first"`）。


```matlab
index("abcdefghijdexxxde", "de", "first")
index("abcdefghijdexxxde", "de", "last")
```

    ans = 4
    ans = 16


`rindex(s, t)` は `index(s, t, "last")` と同じである。


```matlab
 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()` はすべての開始位置を検索する。


```matlab
strfind("set the character used to separate the filename", "the")
```

    ans =
    
        5   36
    



```matlab
strfind("set the character used to separate the filename", "xxx")
```

    ans = [](0x0)



```matlab
strfind("abababa", "aba", "overlaps", false) # オーバーラップを許さない
```

    ans =
    
       1   5
    



```matlab
strfind("abababa", "aba") # オーバーラップを許す（デフォルト）
```

    ans =
    
       1   3   5
    


## 5.　文字列の比較 

長さが同じ文字列に対して `==` を使うと，それぞれの文字位置で同じかどうかの結果を返す。文字列の長さが異なる場合はエラーになる。


```matlab
"abc" == "abc"
```

    ans =
    
      1  1  1
    


### 5.1.　文字列が同じかどうか `strcmp()`

文字列として同じかどうかは `strcmp()` を使わなければならない。


```matlab
strcmp("abc", "abc")
```

    ans = 1


### 5.2.　最初の数文字が同じかどうか `strncmp()`

最初の数文字だけが同じかどうかは `strncmp()` を使う。


```matlab
strncmp("abcde", "abcxy", 3), strncmp("abcde", "abcxy", 4)
```

    ans = 1
    ans = 0


2 つの引数のいずれかが文字列を要素とするセル配列の場合は，比較結果はセル配列の要素数のベクトルになる。


```matlab
strncmp ("abce", {"abcd", "bca", "abc"}, 3)
```

    ans =
    
      1  0  1
    


### 5.3.　大文字・小文字を無視して比較する `strcmpi()`

アルファベットの大文字・小文字の区別をしない比較は `strcmpi()` を使う。


```matlab
strcmpi("ABCde", "aBcDe")
```

    ans = 1


### 5.4.　大文字・小文字を無視して数文字だけ比較する `strncmpi()`

アルファベットの大文字・小文字の区別をしないで最初の数文字だけで比較する場合は `strncmpi()` を使う。


```matlab
strncmpi("ABCde00", "aBcDe99", 5)
```

    ans = 1


## 6.　文字列を取り出す`strtok()`

先頭から区切り文字の前までの文字列を取り出す。区切り文字は複数指定可能（デフォルトでは空白）。


```matlab
strtok("abc def ghi")
```

    ans = abc



```matlab
strtok("abc def ghi", "f")
```

    ans = abc de


戻り値を指定することにより，取り出された文字列と残りの文字列を得ることができる。


```matlab
[token, remind] = strtok ("14*27+31", "+-*/")
```

    token = 14
    remind = *27+31


## 7.　文字列の分割

### 7.1.　文字列分割 `strsplit()`

デリミター 1 文字（デフォルトでは空白）で文字列を分割する。

複数のデリミターを指定するときは，次項の`ostrsplit()` を使用するか，正規表現を使い `"delimitertype"， "regularexpression"` とする。


```matlab
strsplit("foo bar baz")
```

    ans =
    {
      [1,1] = foo
      [1,2] = bar
      [1,3] = baz
    }
    



```matlab
strsplit("foo bar baz", " ")
```

    ans =
    {
      [1,1] = foo
      [1,2] = bar
      [1,3] = baz
    }
    


戻り値を指定することにより，取り出された文字列とマッチした文字列を得ることができる。


```matlab
[word, matches] = strsplit("foo@bar@baz", "@")
```

    word =
    {
      [1,1] = foo
      [1,2] = bar
      [1,3] = baz
    }
    
    matches =
    {
      [1,1] = @
      [1,2] = @
    }
    



```matlab
[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()`


```matlab
ostrsplit("foo@bar,baz", "@,")
```

    ans =
    {
      [1,1] = foo
      [1,2] = bar
      [1,3] = baz
    }
    


## 8.　文字列連結 `strcat()`, `strvcat()`, `char()`

文字列を連結して 1 つの文字列にする。

`strcat()` は横方向に連結する。`[文字列1, 文字列2, ...]` と同じ結果になる。


```matlab
strcat("aaa", "999", "#$%")
```

    ans = aaa999#$%


`strvcat()` は縦方向に連結する。つまり，複数の文字列ベクトルになる。`[文字列1; 文字列2; ...]` と同じ結果になる。


```matlab
a = strvcat("aaa", "999", "#$%")
```

    a =
    
    aaa
    999
    #$%
    


`char()` は引数の指定法により `strcat()`, `strvcat()` と同じ結果を生み出す。


```matlab
char("aaa", "999", "#$%")
```

    ans =
    
    aaa
    999
    #$%
    



```matlab
char(["aaa"; "999"; "#$%"])
```

    ans =
    
    aaa
    999
    #$%
    



```matlab
char(["aaa", "999", "#$%"])
```

    ans = aaa999#$%



```matlab
char([98, 97, 110, 97, 110, 97])
```

    ans = banana


## 9.　文字配列の結合 `strjoin()`

セル文字列を結合して 1 つの文字列にする。


```matlab
strjoin({"i", "have", "a", "pen"})
```

    ans = i have a pen


結合するときのデリミターを指定することができる（デフォルトでは 1 個の空白）。


```matlab
strjoin({"i", "have", "a", "pen"}, delimiter=""), ["i", "have", "a", "pen"]
```

    ans = ihaveapen
    ans = ihaveapen



```matlab
strjoin({"i", "have", "a", "pen"}, delimiter=":")
```

    ans = i:have:a:pen



```matlab
strjoin({"i", "have", "a", "pen"}, delimiter="---")
```

    ans = i---have---a---pen


## 10.　小文字に変換 `tolower()`, `lower()`


```matlab
tolower("ABCDE123"), lower("ABCDE123")
```

    ans = abcde123
    ans = abcde123


## 11.　大文字に変換 `toupper()`, `upper()`


```matlab
toupper("abcde123"), upper("abcde123")
```

    ans = ABCDE123
    ans = ABCDE123


## 12.　数値と文字の相互変換

### 12.1.　数値を文字に変換 `char()`


```matlab
char(0x61)
```

    ans = a



```matlab
char(97:122)
char([98, 97, 110, 97, 110, 97])
```

    ans = abcdefghijklmnopqrstuvwxyz
    ans = banana



```matlab
char([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
```

    ans =
    
    abc 
        
    98  
    99  
    d   
    str1
    half
    


### 12.2.　文字を数値に変換 `int**()`


```matlab
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()`


```matlab
num2str(int32(123)), num2str(123.0), num2str(123.456)
```

    ans = 123
    ans = 123
    ans = 123.456


#### 13.1.2.　`disp()`

`disp()` を使う場合，文字列の最後に改行記号(LF)がつく。


```matlab
a = disp(123.456)
class(a), typeinfo(a)
```

    a = 123.46
    
    ans = char
    ans = sq_string



```matlab
printf("**%s**", a)
```

    **123.46
    **


```matlab
int32(a(end)) # 0xa; LF(line feed)
```

    ans = 10


改行記号を取り除くためには `deblank()` を使えばよい。


```matlab
b = deblank(disp(123.456))
```

    b = 123.46



```matlab
printf("**%s**", b)
```

    **123.46**

#### 13.1.3.　`sprintf()`

`sprintf()` を使えば，任意の形式で文字列に変換できる。


```matlab
b = sprintf("%g", 123.456)
class(b), typeinfo(b)
```

    b = 123.456
    ans = char
    ans = string



```matlab
printf("**%s**", b)
```

    **123.456**

### 13.2.　文字列を数値に変換する

#### 13.2.1.　`str2num()`

`"123, 456.789"` は 2 つの数値に変換される。


```matlab
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` になる。


```matlab
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()`


```matlab
eval("123.456")
```

    ans = 123.4560000000000


## 14.　空白の除去

### 14.1.　末尾の空白類と NULL の除去 `deblank()`



```matlab
printf("'%s'\n", deblank("  abcdef   "))
```

    '  abcdef'


引数が文字行列の場合は，各行の長い方に合わせて空白が除去される。


```matlab
s = deblank([" foo678     "
             "   bar123 "]);
printf("'%s'\n'%s'\n", s(1, :), s(2, :))
```

    ' foo678  '
    '   bar123'


引数がセル配列の場合は，各要素について再帰的に空白が除去される。


```matlab
deblank({" abc  ", {" def   ", "  uvxyz"}})
```

    ans =
    {
      [1,1] =  abc
      [1,2] =
      {
        [1,1] =  def
        [1,2] =   uvxyz
      }
    
    }
    


### 14.2.　先頭と末尾の空白の除去 `strtrim()`



```matlab
printf("'%s'\n", strtrim("  abcdef   "))
```

    'abcdef'


引数が文字行列の場合は，各行の長い方に合わせて空白が除去される。


```matlab
s = strtrim([" foo678     "
             "   bar123 "]);
printf("'%s'\n'%s'\n", s(1, :), s(2, :))
```

    'foo678  '
    '  bar123'


引数がセル配列の場合は，各要素について再帰的に空白が除去される。


```matlab
strtrim({" abc  ", {" def   ", "  uvxyz"}})
```

    ans =
    {
      [1,1] = abc
      [1,2] =
      {
        [1,1] = def
        [1,2] = uvxyz
      }
    
    }
    


## 15.　文字列の切り詰め `strtrunc()`


```matlab
strtrunc("abcdefghij", 5)
```

    ans = abcde


文字行列の場合は，各行に対して文字列が切り詰められる。


```matlab
strtrunc(["abcdefghij"; "0123"; "qwertyuiop"; "!@#$%^&*()"], 5)
```

    ans =
    
    abcde
    0123 
    qwert
    !@#$%
    


セル配列の場合，セルはネストしてはいけない。


```matlab
strtrunc({"abc", "def9", "uvxyz"}, 2)
```

    ans =
    {
      [1,1] = ab
      [1,2] = de
      [1,3] = uv
    }
    


## 16.　任意の長さの空白文字列 `blanks()`


```matlab
printf("+++++%s*****\n", blanks(5))
```

    +++++     *****


## 17.　文字列の空白パディング `strjust()`


```matlab
s = ["a"; "foo"; "super"];
```

### 17.1.　左揃え


```matlab
strjust(s, "left")
```

    ans =
    
    a    
    foo  
    super
    


### 17.2.　中央揃え


```matlab
strjust(s, "center")
```

    ans =
    
      a  
     foo 
    super
    


### 17.3.　右揃え


```matlab
strjust(s, "right")
```

    ans =
    
        a
      foo
    super
    


## 18.　ダブルクオートで囲まれた文字列か? `is_dq_string()`

ダブルクオートで囲まれた文字列のとき `true` を返す。


```matlab
is_dq_string("abc"), is_dq_string('abc')
```

    ans = 1
    ans = 0


## 19.　シングルクオートで囲まれた文字列か? `is_sq_string()`

シングルクオートで囲まれた文字列のとき `true` を返す。


```matlab
is_sq_string("abc"), is_sq_string('abc')
```

    ans = 0
    ans = 1



```matlab
class("abc"), class('abc')
```

    ans = char
    ans = char


## 20.　文字配列か？ `ischar()`

`x` が文字配列（スカラーの場合も含む）のとき `true` を返す。


```matlab
ischar('xy'), ischar("bcd"), ischar(["a", "b", "x"]), ischar([9, 8])
```

    ans = 1
    ans = 1
    ans = 1
    ans = 0


## 21.　文字種

文字の種類を判定する。

### 21.1.　アスキー文字か? `isascii()`


```matlab
isascii(['a', '1', '#'])
```

    ans =
    
      1  1  1
    



```matlab
isascii(['a', '1', char(230)])
```

    ans =
    
      1  1  0
    


### 21.2.　制御文字か? `iscntrl()`


```matlab
iscntrl(['a', '1', "\n"])
```

    ans =
    
      0  0  1
    


### 21.3.　10 進数字か? `isdigit()`


```matlab
isdigit(['a', '1', "\n"])
```

    ans =
    
      0  1  0
    


### 21.4.　16 進数字か? `iaxdigit()`


```matlab
isxdigit(['a', '1', 'F', 'x'])
```

    ans =
    
      1  1  1  0
    


### 21.5.　小文字か? `islower()`


```matlab
islower(['a', 'A'])
```

    ans =
    
      1  0
    


### 21.6.　大文字か? `isupper()`


```matlab
isupper(['a', 'A'])
```

    ans =
    
      0  1
    


### 21.7.　プリントできるか?

#### 21.7.1.　空白を含む `isprint()`


```matlab
isprint([" ", "1", "a"])
```

    ans =
    
      1  1  1
    


#### 21.7.2.　空白は含まない `isgraph()`


```matlab
isgraph([" ", "1", "a"])
```

    ans =
    
      0  1  1
    


### 21.8.　区切り文字か? `ispunct()`


```matlab
ispunct([",", ":", ";", "-", "\n"])
```

    ans =
    
      1  1  1  1  0
    


### 21.9.　空白類か？ `isspace()`


```matlab
isspace([" ", "\t", "\f", "\r", "\n"])
```

    ans =
    
      1  1  1  1  1
    


## 22.　文字列を評価する `eval()`, `evalc()`


```matlab
eval("x = sqrt(8)")
```

    x = 2.828427124746190


第 1 引数の評価が失敗すると，第 2 引数が評価される。


```matlab
eval("sqrt()", "99999")
```

    ans = 99999


評価した結果を文字列で返す。


```matlab
s = evalc("x = sqrt(8)");
s
x
```

    s = x = 2.828427124746190
    
    x = 2.828427124746190


## 23.　問題1

任意の文字を任意個数繰り返す文字列，たとえば `"@@@@@"` を作るにはどうすればよいか。


```matlab
repelem("@", 5)' # 最後の ' が必須
```

    ans = @@@@@


## 24.　問題2

任意の文字列を任意組数繰り返す文字列，たとえば `"@＊#@*#@*#@*#"` を作るにはどうすればよいか。


```matlab
reshape(reshape(repelem("@*#", 4), 4, 3)', 1, 12)
```

    ans = @*#@*#@*#@*#



```matlab
reshape(reshape(repelem("@*#", 4), 4, [])', 1, []) # 要素数の指定を省略できる
```

    ans = @*#@*#@*#@*#