正则表达式匹配字符串中的少数字符

时间:2014-04-06 17:49:36

标签: regex string algorithm

我正在尝试在另一个字符串中找到一个字符串。但是,即使一个或多个字符不匹配,我也会尝试匹配。

让我用一个例子来解释:

假设我有一个字符串'abcdefghij'。现在,如果要匹配的字符串是'abcd'

我可以写strfind('abcdefghij','abc')

现在,我有一个字符串'adcf'。请注意,两个字符不匹配,我认为它是匹配。

知道该怎么做吗?

我知道,这不是最优化的代码。

示例:

a='abcdefghijk';
b='xbcx'
c='abxx'
d='axxd'
e='abcx'
f='xabc'
g='axcd'
h='abxd'
i ='abcd'

所有这些字符串都应与a匹配。我希望这个例子能说明一点。这个想法是,如果1或2个字符也不匹配,则应将其视为匹配。

2 个答案:

答案 0 :(得分:2)

你可以这样做:

A = 'abcdefghij'; % Main string
B = 'adcf'; % String to be found
tolerance = 2; % Maximum number of different characters to tolerate

nA = numel(A);
nB = numel(B);
pos = find(sum(A(mod(cumsum([(1:nA)' ones(nA, nB - 1)], 2) - 1, nA) + 1) == repmat(B, nA, 1), 2) >= nB - tolerance);

在这种情况下,它会返回 pos = [1 3]'; ,因为“ adcf ”可以在第一个位置匹配(匹配“ a? c?“)和第三个位置(匹配”?d?f “)

<强>解释

  • 首先,我们采用A和B的大小
  • 然后,我们创建矩阵[(1:nA)' ones(nA, nB - 1)],它给出了我们:

输出:

 1     1     1     1
 2     1     1     1
 3     1     1     1
 4     1     1     1
 5     1     1     1
 6     1     1     1
 7     1     1     1
 8     1     1     1
 9     1     1     1
10     1     1     1
  • 我们使用cumsum向右执行累积总和,以实现此目的:

输出:

 1     2     3     4
 2     3     4     5
 3     4     5     6
 4     5     6     7
 5     6     7     8
 6     7     8     9
 7     8     9    10
 8     9    10    11
 9    10    11    12
10    11    12    13
  • 并使用mod函数,因此每个数字介于1和nA之间,如下所示:

输出:

 1     2     3     4
 2     3     4     5
 3     4     5     6
 4     5     6     7
 5     6     7     8
 6     7     8     9
 7     8     9    10
 8     9    10     1
 9    10     1     2
10     1     2     3
  • 然后我们使用该矩阵作为A矩阵的索引。

输出:

abcd
bcde
cdef
defg
efgh
fghi
ghij
hija
ijab
jabc

请注意,此矩阵具有A的所有可能子串,大小为nB。

  • 现在我们使用repmat向下复制B,'nA行'。

输出:

adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
  • 并进行直接比较:

输出:

 1     0     1     0
 0     0     0     0
 0     1     0     1
 0     0     0     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
  • 向右汇总给我们:

输出:

2
0
2
0
0
0
0
0
0
0

每个可能子字符串的字符匹配数。

  • 要完成,我们使用find选择容差范围内的匹配索引。

答案 1 :(得分:1)

在您的代码中

c=a-b无效(矩阵尺寸不相同)

如果您需要至少一个匹配,而不是按顺序(如您的示例所示),您可以使用以下内容: -

>> a='abcdefgh';
>> b='adcf';
>> sum(ismember(a,b)) ~= 0

ans =

     1