Clear Filters
Clear Filters

MATLAB R2019aでsub​strが見つかりませ​ん。原因はなんでしょ​うか?

6 views (last 30 days)
masaru tomisaka
masaru tomisaka on 9 Jan 2020
Edited: Tomotaka Hirata on 14 Aug 2020
MATLAB R2019a でsubstrが見つかりません。原因はなんでしょうか?
ドキュメンテーションを確認したところ、R2018bから導入されているらしいのですが、コマンドを叩いても表示されず困っています。

Answers (2)

michio
michio on 9 Jan 2020
Edited: michio on 9 Jan 2020
試しに
which -all substr
とコマンドを実行した結果を教えて頂けますか?
***以下追記***
失礼しました。上のコマンドでは出てきませんね。substr は関数というよりも Stateflow 内に用意された(Stateflow 内で使用するための)演算子なので出てこないのかと。
もし Stateflow 外で文字列を取り扱う場合には
も参照ください。
  2 Comments
masaru tomisaka
masaru tomisaka on 9 Jan 2020
ご回答ありがとうございます。
substr は関数というよりも Stateflow 内に用意された(Stateflow 内で使用するための)演算子なので出てこないのかと。
なるほど。Matlabで使用するためのものではないために表示されなかったのですね。
https://jp.mathworks.com/help/stateflow/string-data.html
もし Stateflow 外で文字列を取り扱う場合には
https://jp.mathworks.com/help/matlab/characters-and-strings.html
も参照ください。
ありがとうございます。解決しました。
substrの代わりにextractAfter等を使用して対応できそうです。
michio
michio on 9 Jan 2020
解決とのことよかったです。コメント頂きありがとうございます。

Sign in to comment.


Tomotaka Hirata
Tomotaka Hirata on 14 Aug 2020
Edited: Tomotaka Hirata on 14 Aug 2020
僕の場合は自分で作りました。
substr = (@(s_or_c, i, n)feval(@(c, i, n) c(i:(i+n-1)),feval(@(s_or_c) char(s_or_c),s_or_c),i,n));
これをコマンドラインにコピペすれば、substrを書き換えたりclear substrしたりしない限り、substrが利用可能になります。
substr("hello world", 2, 6)
と打てば「'ello w'」が返ります。
以下、解説
入力cが文字ベクトル(1重引用符で括られたもの)のとき、
「無名関数」というのを利用して定義すればいいです。
substr = @(c,i,n) c(i:(i+n-1));
とすることで、substrが実現します。
無名関数
@(x, ..) 関数や演算子など(x, ..);
は、
function rtn = anonymous(x, ..)
rtn = 関数や演算子など(x, ..)
end
のようなanonymous.mが「あるとみなして」anonymous(x, ...)を返してくれという命令です。
つまり、先ほどのコードでは、
function rtn = anonymous(c, i, n)
rtn = c(i:(i+n-1));
end
がある
とみなして、
substr = anonymous(c,i,n);
をやったのと同じです。
例えば
substr('hello world', 2, 6)
は'ello w'を返却します。
しかし、ここにはまだ問題が残っています。
substr("hello world", 2, 6)
は機能しないのです。
2重引用符で括られたものは「文字列」であり、文字ベクトルとは別物だからです。
文字列は、char(文字列)のようにすることで文字ベクトルに変換できます。
(蛇足: ちなみにchar(文字ベクトル)は、そっくりそのまま文字ベクトルを返します)
したがって、
substr(char("hello world"), 2, 6)
ならOKです。
ただ、これではダサいですよね。
substr("hello world", 2, 6)
でもちゃんと動くようにしましょう。
substr = @(str,i,n) char(str)(i:(i+n-1));
ならいいでしょうか?
いいえ。
matlabでは、括弧が隣り合うと、エラーになります。
したがって、
substr = @(str,i,n) (c = char(str); c(i:(i+n-1)));
でいけそうです。
しかしこれもダメです。無名関数は文を1つしか持たせられないからです。
何とかして無名関数で書きたい場合、
「feval関数」というのを何度も用いることで書けます。
fevalは、次のような関数です。
feval(@f, x)  が f(x) を返却する」
feval(@g, x, y)g(x, y)を返却する」
・・・
例1:
feval(@cos, 3.14)
は、cos(3.14)つまり-1を返却します。
例2:
feval(@mod, 10,3)
は、mod(10,3)つまり1 を返却します。
また、
feval関数の第1引数には無名関数も持ってこれます。
例3:
feval(@(c,i,n) c(i:(i+n-1)), 'hello_world', 2, 6)
は、substr('hello world', 2, 6)つまり'ello w'を返します。
ややこしいですが、
'無名関数'内でfevalを利用し、
そのfeval内で'無名関数'を利用し、
その'無名関数'内でfevalを利用し
そのfeval内で'無名関数'を利用し、
その'無名関数'内でfevalを利用し
そのfeval内で...
のようなことを繰り返すと、複数の文を無名関数で実行できます。
(理由は、「複数の文」全体を、一つの文としてみることが可能になるからです)
いきなり例を示すと混乱するので(もし皆さんが混乱しないとしても、説明している僕のほうが混乱します笑)、
どんな無名関数をつかうか、先に決めましょう。
関数その1: (s_or_c) → c
引数:
s_or_c: 文字列かもしれないし文字ベクトルかもしれないもの。
戻り値:
c: 確実に文字ベクトル
内容(分かりやすい表現):
c = char(s_or_c);
内容(無名関数の書き方で)
@(s_or_c) char(s_or_c);
関数その2: (c, i, n) → answer
引数:
c
i
n
戻り値:
answer: 得たい部分文字列
内容(分かりやすい表現):
answer = c(i:(i+n-1));
内容(無名関数の書き方で)
@(c, i, n) c(i:(i+n-1));
では、これを書いてみましょう。
substr = ...
(...
@(s_or_c, i, n) ...
feval ... %◆
... %関数その2を無名で定義し、利用します。 %◆
(... %◆
@(c, i, n) c(i:(i+n-1)), ... %◆
... %関数その2を定義 %◆
... %◆
feval ... %★ %◆
... %関数その1を無名で定義し、利用します。%★ %◆
(... %★ %◆
@(s_or_c) char(s_or_c), ... %★ %◆
... %関数その1を定義 %★ %◆
... %★ %◆
s_or_c ... %★ %◆
... %関数その1を利用 %★ %◆
), ... %★ %◆
... %★全体がcとして評価される(=あたかもcであるかのように振る舞う) %◆
i, n ... %(★=c)と繋げて読むと、c,i,nとなっている。 %◆
... %関数その2を利用 %◆
)... %◆
... %◆全体がanswerとして評価される
);
こんな感じです。
それでは、失礼いたします。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!