regular expression to replace ~ in code

Edit: wrote new function StripTildes.m (see below) that works with all cases including output list on multiple lines
Edit: Modified the StripTildes function to use Daniel's regular expression from FEX function. This still does not work with modified TestFunction that uses a line continuation in the output argument list.
My version of Matlab does not support the use of ~ in an output argument list so it is giving syntax errors when I try to use some downloaded code.
My regular expressions are extremely rusty so I would appreciate a regular expression to use with regexprep to replace the ~ in an output argument enclosed in brackets but not replace ~= and other uses of the symbol.
responding to Azzi's comment: I would like to replace ~ with a regular variable name like 'dummy' so it will not cause a syntax error. The rest of the code should then work OK so long as there is no collision with an existing variable name.
My idea is to write a Matlab function to scan the downloaded code file, replace the ~'s, and then write the output to another file.
My editor 'Editpad' allows regular expression search and replace so I can also use the regular expression with it but for definiteness please stick with regexprep and I will take it from there.
Question: I am no clear the allowable syntax. Are only spaces between output arguments allowed such as?
[~ ~ y3 ] = NewFunction(foo);
TIA.
I created a function to implement the filtering and a test function as follows:
1. the filtering function
function StripTildes(filename)
% replace tildes in output parameter lists with 'the_dummy'
% in Matlab file filename
% outputs new file named filename_notilde.m to same directory as original file
pattern='~(?=[^\]\[='']*\][\s(\.\.\.)]*=[^=])'; % regular expression to find tildes
fid = fopen(filename); % open for read only
assert( fid ~= -1);
% read all file into one long string (including line break chars) so regexprep can work across lines
filetext = [];
while 1
tline = fgets(fid);
if ~ischar(tline), break, end % quit at end of file
filetext = [filetext tline];
end
fclose(fid);
filetext = regexprep(filetext,pattern,'the_dummy');
% output the file
[path,name,ext] = fileparts(filename);
out_name = [path filesep name '_notilde' ext];
fidout = fopen(out_name,'w');
assert( fid ~= -1);
fwrite(fidout,filetext);
fclose(fidout);
2. the function to test
function TestFunction
if 1 ~= 0
[~,~,y] = LocalFunction;
elseif ~(true) or ~exist(foo,'dir')
[~ ~ y ] = LocalFunction;
end
tf = [~true, 1~=0, ...
];
[~,~, ...
y] = LocalFunction;
function [y1,y2,y3] = LocalFunction
y1 = 0;
y2 = 0;
y3 = 0
p.s. I cannot afford to upgrade my Matlab version so please do not suggest it as a solution

댓글 수: 6

Azzi Abdelmalek
Azzi Abdelmalek 2013년 7월 11일
편집: Azzi Abdelmalek 2013년 7월 11일
Give an example, and replace ~ with what?
Robert Alvarez
Robert Alvarez 2013년 7월 11일
I updated my original post to answer your question.
Tilde, ~, is allowed in more places, e.g.
>> ~(true)
ans =
0
Daniel Shub
Daniel Shub 2013년 7월 11일
While not wanting to upgrade your MATLAB is reasonable, this means you are running R2007a or earlier. There is no guarantee that new code from the FEX will work on such an old version. I would highly suggest checking the code carefully for other incompatibilities.
per isakson
per isakson 2013년 7월 11일
편집: per isakson 2013년 7월 11일
I modified the expression below to handle [~,~,y] and [~,a,~]
Robert Alvarez
Robert Alvarez 2013년 7월 11일
I fixed a bug in StripTildes function and modified TestFunction.

댓글을 달려면 로그인하십시오.

 채택된 답변

per isakson
per isakson 2013년 7월 11일
편집: per isakson 2013년 7월 11일

0 개 추천

regexprep( '[ a, ~, b ]', '(?<=\[.+?,[ ]*)\~(?=.+?])', 'dummy' )
returns
[ a, dummy, b ]
Firstly, backup all your files
and make more tests
.
Always check the FEX. See replaceTildes
.
Bugfix:
str = '[~,~,y] = LocalFunction;';
regexprep( str, '(?<=\[(.+?,)|([ ]*)[ ]*)\~(?=.+?])', 'dummy' )
returns
ans =
[dummy,dummy,y] = LocalFunction;
.
and another bugfix
str = '[~,a,~] = LocalFunction;';
regexprep( str, '(?<=\[(.+?,)|([ ]*)[ ]*)\~(?=.*?])', 'dummy' )
returns
ans =
[dummy,a,dummy] = LocalFunction;
and more test needed

댓글 수: 7

Robert Alvarez
Robert Alvarez 2013년 7월 11일
I tested this regular expression using the code I placed in the original question and it did not work. Perhaps because I did not use spaces between the ~'s although I think this is legal syntax?
That seemed to work. I tested it on
function TestFunction
function TestFunction
[~,~,y] = LocalFunction;
[~ ~ y ] = LocalFunction;
function [y1,y2,y3] = LocalFunction
y1 = 0;
y2 = 0;
y3 = 0;
and got this
[dummy,dummy,y] = LocalFunction;
[dummy dummy y ] = LocalFunction;
function [y1,y2,y3] = LocalFunction
y1 = 0;
y2 = 0;
y3 = 0;
Thanks for the link to the FEX. BTW, I fixed a bug in my StripTildes function in the OP.
per isakson
per isakson 2013년 7월 11일
편집: per isakson 2013년 7월 11일
I was about to write something on anti-pattern. I found an expression that handled one simple case. Next, I modified the expression in response to a bug. New bug and one more modification. This can go on forever and the expression becomes so complicated and brittle that it is useless.
BTW:
  • I have not used the fact that to right of the match there should be an equal sign. (What about continuation lines?)
  • This search_and_replace should not be done on comments
per isakson
per isakson 2013년 7월 11일
A better way is
  • collect as many different examples - both cases which should match and cases which should not.
  • formulate a rule in plain English
  • implement that rule as a regular expression
  • test with all the cases of the first step
Robert Alvarez
Robert Alvarez 2013년 7월 11일
I found a test case that does not work with the regular expression in this answer or in replaceTildes.m function. See the original post.
per isakson
per isakson 2013년 7월 11일
편집: per isakson 2013년 7월 11일
Try this
reg = '(?<=\[(.+?,)|([ ]*)[ ]*)\~(?=.*?][ ]*(=|(\.\.\.)))';
str = '[~,a,~] = LocalFunction;';
regexprep( str, reg, 'dummy' )
str = 'tf = [~true, 1~=0, ...';
regexprep( str, reg, 'dummy' )
str = '[~,a,~] ...';
regexprep( str, reg, 'dummy' )
The expression looks at one line. Thus, I give up on this one
[~,~, ...
y] = LocalFunction;
and after that we will face
[y,~, ...
~] = LocalFunction;
You could
  • concatenate the continuation lines
  • search&replace
  • restore the continuation lines
per isakson
per isakson 2013년 7월 11일
FileLocator Lite is a free really good find_in_files_program. It will help you find the remaining cases, which you should edit interactively.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Azzi Abdelmalek
Azzi Abdelmalek 2013년 7월 11일
편집: Azzi Abdelmalek 2013년 7월 11일

0 개 추천

str='one ~ two ~= three ~'
pattern='~(?!\S)'
regexprep(str,pattern,'dummy')

댓글 수: 2

Daniel Shub
Daniel Shub 2013년 7월 11일
I think this will fail if the ~ is in a string. It is possibly better to also include [] since I think that is a requirement. I think counting opening/closing quoutes might be hard.
Azzi Abdelmalek
Azzi Abdelmalek 2013년 7월 11일
편집: Azzi Abdelmalek 2013년 7월 11일
str=' z~d one ~ two ~= three ~'
pattern='~(?!\=)'
regexprep(str,pattern,'dummy')
%or
str=strrep(str,'~=','obma')
str=strrep(str,'~','dummy')
str=strrep(str,'obma','~=')

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Performance and Memory에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by