Testing for the presence of a substring in a cell array of strings

38 views (last 30 days)
*NEWBIE WARNING***
I have a very basic question but couldn't find an answer after searching.
I wish to test if a multi-element cell array of strings contains a substring anywhere within the cell array's text, returning a logical true or false answer. For example, given the cell array of strings x:
x = {'qwer','asdf','zxcv'};
I wish to test if the substring 'xc' is present somewhere in x's text (true in this example).
The method I came up with is as follows:
First, concatenate the elements of the cell array of strings into a single character string, preserving the original character order:
y = char(x);
y = y';
y = y(:)'; % y now equals 'qwerasdfzxcv'
Then, test for the presence of the substring in the concatenated string:
~isempty(strfind(y,'xc')) % ans = true
~isempty(strfind(y,'123')) % ans = false
Is there a better way to do this that involves less array manipulation? Thank you for your assistance.

Accepted Answer

Sean de Wolski
Sean de Wolski on 12 Oct 2012
matches = strfind(x,'xc');
tf = any(vertcat(matches{:}))
  2 Comments
Matt Fig
Matt Fig on 12 Oct 2012
Edited: Matt Fig on 12 Oct 2012
This can error if there is a different number of matches per string. For example:
x = {'qwerxc','xcaxcsdf','zxcvxcllxc'};
One could simply switch to using HORZCAT.
I would use:
tf = any(~cellfun('isempty',strfind(x,'xc')))
Schuyler
Schuyler on 14 Oct 2012
Thank you for this clarification and for the suggestion to use HORZCAT.

Sign in to comment.

More Answers (4)

per isakson
per isakson on 12 Oct 2012
Edited: per isakson on 12 Oct 2012
Here is a construct without implicit casting of types
is_xc = not( cellfun( @isempty, strfind( x, 'xc' ) ) );
and next
any( is_xc )
Easier to read
is_xc = cellfun( @has_value, strfind( x, 'xc' ) ) );
where
function has = has_value( input )
has = not( isempty( input ) );
end

Azzi Abdelmalek
Azzi Abdelmalek on 12 Oct 2012
Edited: Azzi Abdelmalek on 12 Oct 2012
x = {'qwer','asdf','zxcv'};
out=any(cell2mat(cellfun(@(y) regexp(y,'xc'),x,'un',0)))
or
out=any(cell2mat(regexp(x,'xc')))

Demetrio Rodriguez Tereshkin
OP has already given, in my opinion, the best answer. Although it has to be corrected: isempty() always returns 1 for the type "cell", therefore we should use
cellfun(@isempty,strfind(y,'123'))

Schuyler
Schuyler on 12 Oct 2012
Edited: Schuyler on 14 Oct 2012
Wow, all three methods are great! I find:
matches = strfind(x,'xc');
tf = any(horzcat(matches{:}))
to be the simplest to visualize because it doesn't involve regular expressions or functions, but they are clearly all effective techniques. Thank you very much for the quick and helpful responses.
  1 Comment
Leo Simon
Leo Simon on 25 Apr 2020
Edited: Leo Simon on 25 Apr 2020
This code extends AA's answer to when you need to check if a substring of a string is contained in a cell array:
needLatexForThese = {'\bar','\ubar','\check','\hat'};
stringYes = '$\bar{x}$'
stringNo = '$x^\ast$'
f = @(s) any(cell2mat(cellfun(@(y) contains(s,y),needTexForThese,'un',0)));
f(stringYes)%returns 1
f(stringNo)%returns 0

Sign in to comment.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!