对于不熟悉 MATLAB 的读者:不确定它们属于哪个系列,但此处详细描述了 MATLAB 正则表达式。MATLAB 的注释字符是%
(percent),其字符串分隔符是'
(撇号)。字符串中的字符串定界符写成双撇号 ( 'this is how you write "it''s" in a string.'
)。更复杂的是,矩阵转置运算符也是撇号(A'
(Hermitian)或A.'
(regular))。
现在,出于黑暗的原因(我不会详细说明:),我正在尝试用 MATLAB 自己的语言解释 MATLAB 代码。
目前,我正在尝试删除字符串单元格数组中的所有尾随注释,每个字符串都包含一行 MATLAB 代码。乍一看,这似乎很简单:
>> str = 'simpleCommand(); % simple trailing comment';
>> regexprep(str, '%.*$', '')
ans =
simpleCommand();
但是,当然,可能会出现这样的情况:
>> str = ' fprintf(''%d%*c%3.0f\n'', value, args{:}); % Let''s do this! ';
>> regexprep(str, '%.*$', '')
ans =
fprintf(' %// <-- WRONG!
显然,我们需要从匹配项中排除所有位于字符串中的注释字符,同时还要考虑到语句之后的单个撇号(或点撇号)是运算符,而不是字符串分隔符。
基于注释字符之前的字符串打开/关闭字符的数量必须是偶数的假设(我知道这是不完整的,因为矩阵转置运算符),我想出了以下动态正则表达式来处理这种情况:
>> 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')
然而,
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)
所以我快到了,但还没有:)
不幸的是,我已经用尽了我可以花时间思考这个问题并且需要继续做其他事情,所以也许其他有更多时间的人足够友好地思考这些问题:
- 字符串中的注释字符是我需要注意的唯一例外吗?
- 这样做的正确和/或更有效的方法是什么?