многократное использование мобильного телефона

Используя команду get_param(maskBlock,'MaskVariables'), я получаю строку, которая выглядит так:

'AB=@1;AC=@2;AD=@3;AE=@4;..AZ=@26;'

Я хотел изменить числа и добавить к ним 1, чтобы получить:

'AB=@2;AC=@3;AD=@4;AE=@5;..AZ=@27;'

Вот что я закодировал:

strSplit = regexp(theStringFromGetParam , ';', 'split')'; % split the string at the ; to get multiple strings
str1 = cellfun(@(x) str2double(regexp(x,'(\d+)','tokens','once'))+1, strSplit, 'UniformOutput', false); % cell containing the last numbers
str2 = cellfun(@(x) regexp(x,'(\w+)(\W+)','tokens','once'), strSplit, 'UniformOutput', false); % cell containing everything that is not a number
str3 = cellfun(@(x) strcat(x{1}, x{2}), str2, 'UniformOutput', false); % join the two parts from the line above
str4 = cellfun(@(x,y) strcat(x,num2str(y)), str3, str1, 'UniformOutput', false); % join the number numbers with the "letters=@"

Это работает, но я почти уверен, что есть лучший способ сделать это. Кто-нибудь может помочь мне найти лучший способ, чем использовать 4 раза команду cellfun?


person m_power    schedule 27.06.2013    source источник


Ответы (4)


Вот однострочный:

str = 'AB=@1;AC=@2;AD=@3;AE=@4;AZ=@26;';
regexprep(str,'(?<=@)(\d+)','${sprintf(''%d'',str2double($1)+1)}')

Сопоставление выполняется легко: в любой точке строки ищите @, если оно найдено, затем сопоставьте одну или несколько последовательных цифр и зафиксируйте их в токене.

Замена: str2double() захваченный токен, добавить 1 и преобразовать обратно в целое число. Команда выполняется с динамическим выражением '${command}'.

person Oleg    schedule 27.06.2013
comment
Очень хорошо! Я постараюсь все понять (и другой ответ), прежде чем принять окончательный ответ. - person m_power; 27.06.2013

У меня есть ответ без использования cellfun, но с использованием токенов:

%the given string
str = 'AB=@1;AC=@2;AD=@3;AE=@4;..AZ=@26;';
%find the numbers using tokens
regex = '=@(\d+);';
%dynamic replacement - take the token, convert it to a number - add 1 - and
%convert it back to a string
replace = '=@${num2str(str2num($1)+1)};';
%here is your result - replace all found numbers with the replace string
regexprep(str, regexp, replace)
person kiki    schedule 27.06.2013
comment
Я не видел твоего сначала! То же самое по духу, хотя str2num и num2str снижают производительность. - person Oleg; 28.06.2013
comment
хороший ответ. Однако неразумно использовать regexp в качестве имени переменной: это имя встроенной функции! - person Shai; 28.06.2013

Как насчет:

num = regexp( theStringFromGetParam, '@(\d+);', 'tokens' ); % get the numbers
num = cellfun( @(x) str2double(x), num ); % convert to numbers
frmt = regexprep( theStringFromGetParam, '@(\d+);', '@%%d;' );
sprintf( frmt, num ); % print the updated numbers into the format string.
person Shai    schedule 27.06.2013
comment
Мне тоже нравится этот ответ! Будет трудно сделать свой выбор! - person m_power; 27.06.2013
comment
@m_power Я бы согласился с ответом Олега - person Shai; 28.06.2013

Упс, я начал писать это прошлой ночью перед уходом с работы и забыл закончить. Просто пример использования textscan вместо regexp.

ManyCells=textscan(theStringFromGetParam,'%s%d', 'delimiter','@;');
S=arrayfun(@(x) sprintf('%s@%d;',ManyCells{1}{x},1+ManyCells{2}(x)),1:length(ManyCells{1}),'uniformoutput',false)
NewString=cat(2,S{:});

Я пытался поиграть с индексированием и cellfun, чтобы избавиться от arrayfun, но не смог с этим справиться; есть идеи у кого-нибудь?

person Hugh Nolan    schedule 28.06.2013