Arrays MATLAB在字符串的单元格数组中查找子字符串数组的复制数

Arrays MATLAB在字符串的单元格数组中查找子字符串数组的复制数,arrays,string,matlab,Arrays,String,Matlab,我有一个字符串的MATLAB单元格数组和一个部分字符串的第二个数组: base = {'a','b','c','d'} all2 = {'a1','b1','c1','d1','a2','b2','c2','d2','q8','r15'} 输出为: base = 'a' 'b' 'c' 'd' all2 = 'a1' 'b1' 'c1' 'd1' 'a2' 'b2' 'c2' 'd2' 'q8'

我有一个字符串的MATLAB单元格数组和一个部分字符串的第二个数组:

base = {'a','b','c','d'}
all2 = {'a1','b1','c1','d1','a2','b2','c2','d2','q8','r15'}
输出为:

base = 

    'a'    'b'    'c'    'd'


all2 = 

    'a1'    'b1'    'c1'    'd1'    'a2'    'b2'    'c2'    'd2'    'q8'    'r15'
问题/要求

如果
'a1'
'b1'
'c1'
'd1'
'a2'
'b2'
'c2'
中的任何一个都存在于
所有2
数组中,则返回一个变量
numb=2

如果
'a1'
'b1'
'c1'
'd1'
'a2'
'b2'
'c2'
'd2'
,以及
'a3'
'c3'
中的任何一项都出现在 尝试

一,

基于
strfind
(),我尝试了
matches=strfind(all2,base)但是我得到了这个错误:

`Error using strfind`

`Input strings must have one row.`
....
二,

这种使用strfind的方法似乎更好,但却给了我一个机会

fun = @(s)~cellfun('isempty',strfind(all2,s));
out = cellfun(fun,base,'UniformOutput',false)
idx = all(horzcat(out{:}));
idx(1,1) 

out = 

[1x10 logical]    [1x10 logical]    [1x10 logical]    [1x10 logical]


ans =

     0
这两种尝试都没有奏效。我认为我的逻辑是错误的

三,

answer允许在字符串数组中查找部分字符串数组的所有索引。它返回:

base = regexptranslate('escape', base);
matches = false(size(all2));
for k = 1:numel(all2)
    matches(k) = any(~cellfun('isempty', regexp(all2{k}, base)));
end
matches
输出:

matches =

     1     1     1     1     1     1     1     1     0     0
这种方法的问题是:如何使用输出的
匹配项来计算
numb=2
?我不确定这是否与我的具体问题最相关的逻辑,因为它只给出匹配的索引

问题

有没有一种方法可以在MATLAB中实现这一点

编辑

其他信息:


数组
all2
将始终是连续的。
all2={'a1','b1','c1','d1','a3','b3','c3','d3','q8','r15'}
的场景是不可能的。

使用正则表达式查找
基元素的唯一后缀:

base = {'a','b','c','d'};
all2 = {'a1','b1','c1','d1','a2','b2','c2','d2', 'a4', 'q8','r15'};

% Use sprintf to build the expression so we can concatenate all the values
% of base into a single string; this is the [c1c2c3] metacharacter.
% Assumes the values of base are going to be one character
%
% This regex looks for one or more digits preceeded by a character from
% base and returns only the digits that match this criteria.
regexstr = sprintf('(?<=[%s])(\\d+)', [base{:}]);

% Use once to eliminate a cell array level
test = regexp(all2, regexstr, 'match', 'once');

% Convert the digits to a double array
digits = str2double(test);

% Return the number of unique digits. With isnan() we can use logical indexing
% to ignore the NaN values
num = numel(unique(digits(~isnan(digits))));

如果您需要连续数字,那么类似的内容应该是有效的:

base = {'a','b','c','d'};
all2 = {'a1','b1','c1','d1','a2','b2','c2','d2', 'a4', 'q8','r15'};

regexstr = sprintf('(?<=[%s])(\\d+)', [base{:}]);
test = regexp(all2, regexstr, 'match', 'once');
digits = str2double(test);

% Find the unique digits, with isnan() we can use logical indexing to ignore the
% NaN values
unique_digits = unique(digits(~isnan(digits)));

% Because unique returns sorted values, we can use this to find where the
% first difference between digits is greater than 1. Append Inf at the end to
% handle the case where all values are continuous.
num = find(diff([unique_digits Inf]) > 1, 1);  % Thanks @gnovice :)

分解和行:因为我们知道
base
只包含单个字符,所以我们可以使用,它将匹配括号内的任何字符。因此,如果我们有
'[rp]ain'
,我们将匹配
'rain'
'pain'
,而不是
'gain'

base{:}
返回MATLAB调用的值。添加括号将结果连接到单个字符数组中

无括号:

>> base{:}

ans =

    'a'


ans =

    'b'


ans =

    'c'


ans =

    'd'
>> [base{:}]

ans =

    'abcd'
括号内:

>> base{:}

ans =

    'a'


ans =

    'b'


ans =

    'c'


ans =

    'd'
>> [base{:}]

ans =

    'abcd'

我们可以使用
sprintf
将其插入到表达式字符串中。这给了我们
(?当数字不连续时会发生什么?比如
all2={'a1''a3''a4'};
应该返回
numb=3
?@gnovice
numb
应该是
1
case@gnovice我想你的意思是
all2={'a1',a3',a4'};
。如果是这样,那么你是正确的。如果,
all2={'a1','a3','a4'}
那么返回值应该是
numb=3
。使用我在OP中的示例:如果
'a1'、…
'a2'、…
'a3'、…
中的任何一个都出现在
all2
数组中,那么返回一个变量
numb=3
。在他的示例中没有
'a2'、
,是的,没有
a2
e> 。但是,仍然有
a3
a4
。因此需要连续和非连续。我认为此解决方案有效。我仍然在考虑连续/非连续部分。我更新了OP,但可能需要删除它。仍然在想……我添加了具有连续限制的解决方案是的,它需要连续我知道。好的,谢谢你把它们分开。这是非常具体的,我最初没有想到这两种情况。这对我来说很有效。好的,除了前3行,我似乎理解其他行……它们看起来很清楚。只是前3行有点混乱。主要是第1行……你能解释一下你是如何使用
sprintf
来组装
regexp
需要吗?我已经添加了一个regex的分解,希望它能有所帮助。