文字ベクトルのセル配​列から文字の一部だけ​きりとり新たなセル配​列を作る方法を教えて​ください

조회 수: 9 (최근 30일)
浩祐 佐々木
浩祐 佐々木 2021년 9월 24일
댓글: Atsushi Ueno 2021년 9월 27일
例えば下記のような文字列ベクトルのセル配列があるとします
C = {'abcdefg1';'abcdefg2';'abcdefg3';'abcdefg4';'abcdefg5'}
この各行に入っている文字列から次のようなルールで文字列を引き抜き新たなセル配列Dを作る際はどのように書けばよいでしょうか
ルール
先頭3文字を抜く
D = {'defg1';cdefg2';'defg3';'defg4';'defg5'}
大量の手持ちのデータのラベルから新たなデータラベルを作りたいのですが
上記のようなことを記載できず困っております.
ベーシックなことで恐縮ですが教えていただけますと幸いです.

채택된 답변

Atsushi Ueno
Atsushi Ueno 2021년 9월 24일
Cの内容は少し改造しました
C = {'abcdefg1';'bcdefg2';'acdefg3';'defg4';'efg5';'fg6';'g7'}
C = 7×1 cell array
{'abcdefg1'} {'bcdefg2' } {'acdefg3' } {'defg4' } {'efg5' } {'fg6' } {'g7' }
D = cellfun(@(x) x(4:end),C,'uni',false)
D = 7×1 cell array
{'defg1' } {'efg2' } {'efg3' } {'g4' } {'5' } {1×0 char} {1×0 char}
  댓글 수: 2
Akira Agata
Akira Agata 2021년 9월 26일
+1
別の方法として、正規表現を使う手もあります(ただし対象の文字列が3文字以下の場合はうまくいかないので注意が必要ですが)。
D = regexprep(C,'^\w{3}','');
R2020b以降であれば、以下でも可能です。
pat = lineBoundary('start')+alphanumericsPattern(3);
D = erase(C,pat);
Atsushi Ueno
Atsushi Ueno 2021년 9월 26일
편집: Atsushi Ueno 2021년 9월 26일
どちらも対象の文字数を1~3文字にすればうまくいきますよ。
D = regexprep(C,'^\w{1,3}','');
pat = lineBoundary('start')+alphanumericsPattern(1,3);
F = erase(C,pat)
MATLABのpetternは可読性が高くて良いですね。
(追記)ルール(要件)が「先頭3文字を抜く」だから、先頭が1文字または2文字しかない場合にその1文字または2文字を抜いてはならないかもしれませんね。その意味では上記コメントの方が良さそうですね。
C = {'abcdefg1';'bcdefg2';'acdefg3';'defg4';'efg5';'fg6';'g7'};
D = regexprep(C,'^\w{3}','')
D = 7×1 cell array
{'defg1' } {'efg2' } {'efg3' } {'g4' } {'5' } {0×0 char} {'g7' }
pat = lineBoundary('start')+alphanumericsPattern(3);
F = erase(C,pat)
F = 7×1 cell array
{'defg1' } {'efg2' } {'efg3' } {'g4' } {'5' } {0×0 char} {'g7' }

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

浩祐 佐々木
浩祐 佐々木 2021년 9월 24일
早急なご回答誠にありがとうございます.
参考にし書き換え使用させていただきたいとおもいます.
もしよろしければ追加で下記教えていただきたく思います
cellfun(@(x) x(4:end),C,'uni',false)
の@は関数の前に置くルールだとヘルプを読み,そのように理解いたしまいした
(x),とはどのような意味合いなのでしょうか
またその後におく’uni'とは何を表しているでしょうか
恐れ入りますがご教示いただけると幸いです.
  댓글 수: 4
浩祐 佐々木
浩祐 佐々木 2021년 9월 27일
すいません,追記させてください
上記,色々書きましたが
やりたいことは
abcdef_ghi_0_
abcdef_ghi1
abcdef_ghi2
などがあった時にこれらは本質的には
abcdef_ghi
と同じデータなので
大元のデータベースのデータ群からabcdef_ghiを参照しに行って欲しいのです.
ですので「部分一致(?)のように最も整合している文字列」を検索してそれに該当する名前を
大元データベースから提示しれくれるよなことをしたいと考えておるのですが
それを簡便に記述できず...
Atsushi Ueno
Atsushi Ueno 2021년 9월 27일
単純なルールに対しては単純な処理が良いですが、ルールが複雑になってくると@Akira Agataさんの仰る正規表現(最近のMATLABではpettern)の出番です。
大事なのは質問文の冒頭にも出てくる「ルール」を正確に見極める事です。
例えば自分の回答は「先頭3文字を抜く」という要件に対し、確認せずに先頭1~2文字しか無い場合も抜いてしまいました。もしこれが稀に見る事象に合わない場合、不具合を引き起こす時限爆弾になります。
今の例を見る限りのルールを決め、正規表現で必要なキーワードを抜き出してみます
  • 先頭4文字は除く(文字数は固定、短い文字列は絶対に現れない想定)
  • キーワードの文字種類(a~z)と文字数(6文字_3文字)で特定可能(違うかも)
  • キーワードの末尾に数字を含む不規則な文字記号が付くので除きたい
検索パターン「^.{4}([a-z]{3,6}_[a-z]{3})
^   ⇒入力文字列の先頭にマッチする(先頭から始まるパターンにしかマッチしない)
.{4} .は任意の文字、{4}は量指定子(4個ピッタリにマッチする)
(...) ⇒()内をキャプチャする。因みに括弧文字にマッチするのは\(や\)
[a-z]{6} [a-z]a~z1文字、{6}は量指定子(6個ピッタリにマッチする)
_   ⇒これはアンダースコア自体にマッチ。記号によってはエスケープが必要なので注意
G = {'ABCDabcdef_ghi_0_','1234abcdef_ghi0','+*=~abcdef_ghi[0]',...
'M7g3abcdef_ghi_0_','NE#0abcdef_ghi','****abcdef_ghi2'};
H = regexp(G,'^.{4}([a-z]{6}_[a-z]{3})','tokens'); %因みに、先頭4文字を先読みでマッチから外し'match'で結果を得る方法もあります
cellfun(@(x) x{1}{1}, H, 'uni', false) % 結果を表示
ans = 1×6 cell array
{'abcdef_ghi'} {'abcdef_ghi'} {'abcdef_ghi'} {'abcdef_ghi'} {'abcdef_ghi'} {'abcdef_ghi'}

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 文字と文字列에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!