Rod*_*uis 8 regex string matlab parsing
对于非MATLAB的读者:不确定他们属于哪个系列,但是这里将详细介绍MATLAB正则表达式.MATLAB的注释字符是%(百分比),其字符串分隔符是'(撇号).字符串内的字符串分隔符写为double-apostophe('this is how you write "it''s" in a string.').更复杂的是,矩阵转置运算符也是撇号(A'(Hermitian)或A.'(常规)).
现在,由于黑暗的原因(我不会详细说明:),我试图用MATLAB自己的语言解释MATLAB代码.
目前我正在尝试删除字符串单元格数组中的所有尾随注释,每个字符串都包含一行MATLAB代码.乍一看,这似乎很简单:
>> str = 'simpleCommand(); % simple trailing comment';
>> regexprep(str, '%.*$', '')
ans =
simpleCommand();
Run Code Online (Sandbox Code Playgroud)
但是,当然,这样的事情可能会出现:
>> str = ' fprintf(''%d%*c%3.0f\n'', value, args{:}); % Let''s do this! ';
>> regexprep(str, '%.*$', '')
ans =
fprintf(' %// <-- WRONG!
Run Code Online (Sandbox Code Playgroud)
显然,我们需要从匹配中排除驻留在字符串内的所有注释字符,同时还要考虑直接在语句后面的单个撇号(或点 - 对照)是运算符,而不是字符串分隔符.
基于以下假设:注释字符前的字符串打开/关闭字符数必须是偶数(我知道这是不完整的,因为矩阵转置运算符),我想出了以下动态正则表达式来处理这种情况:
>> str = {
'myFun( {''test'' ''%''}); % let''s '
'sprintf(str, ''%*8.0f%*s%c%3d\n''); % it''s '
'sprintf(str, ''%*8.0f%*s%c%3d\n''); % let''s '
'sprintf(str, ''%*8.0f%*s%c%3d\n''); '
'A = A.'';%tight trailing comment'
};
>>
>> C = regexprep(str, '(^.*)(?@mod(sum(\1==''''''''),2)==0;)(%.*$)', '$1')
Run Code Online (Sandbox Code Playgroud)
然而,
C =
'myFun( {'test' '%'}); ' %// sucess
'sprintf(str, '%*8.0f%*s%c%3d\n'); ' %// sucess
'sprintf(str, '%*8.0f%*s%c%3d\n'); ' %// sucess
'sprintf(str, '%*8.0f%*s%c' %// FAIL
'A = A.';' %// success (although I'm not sure why)
Run Code Online (Sandbox Code Playgroud)
所以我差不多了,但还不完全:)
不幸的是,我已经花了很多时间来思考这个并且还需要继续其他事情,所以也许有更多时间的其他人足够友好地思考这些问题:
您对使用未记录的功能有何看法?如果您不反对,可以使用该mtree函数来解析代码并删除注释.没有涉及regexp,我们都知道我们不应该尝试使用正则表达式解析无上下文的语法.
该函数是用纯M代码编写的MATLAB代码的完整解析器.据我所知,它是一个实验性的实现,但它已经被Mathworks在一些地方使用(这与MATLAB Cody和Contests用来测量代码长度的功能相同),并且可以用于其他有用的东西.
如果输入是字符串的cellarray,我们做:
>> str = {..};
>> C = deblank(cellfun(@(s) tree2str(mtree(s)), str, 'UniformOutput',false))
C =
'myFun( { 'test', '%' } );'
'sprintf( str, '%*8.0f%*s%c%3d\n' );'
'sprintf( str, '%*8.0f%*s%c%3d\n' );'
'sprintf( str, '%*8.0f%*s%c%3d\n' );'
'A = A.';'
Run Code Online (Sandbox Code Playgroud)
如果您已经在磁盘上存储了M文件,则可以将注释简单地删除为:
s = tree2str(mtree('myfile.m', '-file'))
Run Code Online (Sandbox Code Playgroud)
如果您想要查看评论,请添加: mtree(.., '-comments')
这通过检查一个字符之前允许使用哪些字符来匹配共轭转置大小写
2'A'A.'A(1)',A{1}'以及[1 2 3]'我现在能想到的就只有这些案例了。
C = regexprep(str, '^(([^'']*''[^'']*''|[^'']*[\.a-zA-Z0-9\)\}\]]''[^'']*)*[^'']*)%.*$', '$1')
Run Code Online (Sandbox Code Playgroud)
在你的例子中我们会返回
>> C = regexprep(str, '^(([^'']*''[^'']*''|[^'']*[\.a-zA-Z0-9\)\}\]]''[^'']*)*[^'']*)%.*$', '$1')
C =
'myFun( {'test' '%'}); '
'sprintf(str, '%*8.0f%*s%c%3d\n'); '
'sprintf(str, '%*8.0f%*s%c%3d\n'); '
'sprintf(str, '%*8.0f%*s%c%3d\n'); '
'A = A.';'
Run Code Online (Sandbox Code Playgroud)