有时需要在一个命令中进行多次调用。一个简单的例子可能是strrep。假设您要用括号替换所有括号,所有逗号用点替换,然后删除所有双引号。然后可能需要以下伪代码:
strrep(myString, '()', '[]', ',', '.', '"', '')
有没有办法实现这个目标?你当然可以选择:
strrep(strrep(strrep(myString, '()', '[]'), ',', '.'), '"', '')
或者将字符串保存在单元格数组中并在for循环中使用它,但这两种解决方案都非常难看。
最理想的答案是对所有以类似方式工作的函数都是通用的。
答案 0 :(得分:5)
要直接回答你的问题,实际上没有一致的方法可以做到这一点,不。这真的取决于功能。如果您搜索文档,您通常会找到一种方法来执行此操作。至少使用字符串,您通常可以通过单元格数组代替字符串来对多个字符串执行操作,在这种情况下,对相同的字符串执行多个操作。
您可以轻松使用regexprep
为您执行此操作。您可以传递表达式的单元格数组以匹配替换值的相应单元格数组。
regexprep('abc', {'a', 'b', 'c'}, {'1', '2', '3'});
%// '123'
对于您的具体示例,您可以执行以下操作:
regexprep(myString, {'\(\)', ',', '"'}, {'[]', '.', ''})
作为一个例子:
myString = 'This, is a () "string"';
regexprep(myString, {'\(\)', ',', '"'}, {'[]', '.', ''})
%// 'This. is a [] string'
如果您不想担心将所有表达式转义为正则表达式兼容,可以使用regexptranslate
为您执行此操作。
expressions = regexptranslate('escape', {'()', ',', '"'});
regexprep(myString, expressions, {'[]', '.', ''});
答案 1 :(得分:1)
假设您希望函数foo
能够像这样工作:
foo(Variable,Parameter1,Value1);
foo(Variable,Parameter1_1,Value1,Parameter2,Value2,...);
然后使用递归:
function[Variable]=FooBar(Variable,varargin)
N=nargin-1; %\\ Count the input parameters
if N>=2
Parameter=varargin{1};
Value=varargin{2};
% Process the first Parameter-value pair
Variable=FooBar(Variable,varargin{3:N}); %\\ Cut first Parameter-Value pair off and pass the rest to foo again
end
这种方法允许您使用单个参数链,对,三元组,四元组等。
在这个相关的示例中,对被执行为LIFO堆栈,最后一个未配对的Parameter
被忽略。您还可以添加一些条件来实现foo(IN,Parameter1,Value1,Modifier,Parameter2,Value2,...)
和许多其他属性...
对于你的个别例子:
function[MyString]=FooBar(MyString,varargin)
N=nargin-1; %\\ Count the input parameters
if N>=2
Parameter=varargin{1};
Value=varargin{2};
MyString=regexprep(MyString,Parameter,Value)
MyString=FooBar(MyString,varargin{3:N});%\\ Cut first Parameter-Value pair off and pass the rest to foo again
end
示例:
>> myString='This, is a () "string"';
FooBar(myString,'()','[]','"','',',','.')
ans = This. is a [] string
>> myString='This, is a ("string")';
FooBar(myString,'()','[]','"','',',','.')
ans = This. is a (string)
>> myString='This, is a ("string")';
FooBar(myString,'(','[',')',']','"','',',','.')
ans = This. is a [string]
答案 2 :(得分:0)
正如@Suever所说,你的例子可以通过regexprep
来解决,而@thewaywewalk已经暗示所有函数调用都没有“通用”解决方案。
注意我并不主张这是一种很好的代码方式 - >但这是一个古怪的问题,因此这是一个合适的古怪解决方案......
有很多理由不应该这样做 - 即调试的噩梦,但理论上你可以通过“智能”自我调用函数做到这一点......
% Create your own function which takes the following inputs:
% fHandle - function handle to the function of choice
% property - your starting variable
% varargin - a cell array (or single var) of variables to
% pass into the fHandle on each call
% see examples below...
function output = multipleCalls ( fHandle, property, varargin )
% call your primary function using feval and your inputs
% with the 1st group of inputs from the 1st varargin
if iscell ( varargin{1} )
output = feval ( fHandle, property, varargin{1}{:} );
else
output = feval ( fHandle, property, varargin{1} );
end
% remove the varargin variable which has just been used.
varargin(1) = [];
% are they aremore multiple call?
if ~isempty ( varargin )
% if so self call to apply the subsequent calls.
output = multipleCalls ( fHandle, output, varargin{:} );
end
end
% modifying your example to use this method:
multipleCalls( @strrep, 'This, is a () "string"', { '()', '[]' }, { ',', '.' }, { '"', '' } )
% Its probably a longer command and is it any clearer -> probably not...
% Here is another example:
% Create a silly anonymous function
sillyFunction = @(a,b) a + b
% Then you can use it in the same way:
% Where 0 is what you start with and then
% each time you want to add 1, then 2, then 3 and finally 4
multipleCalls ( sillyFunction, 0, 1, 2, 3, 4 )