8

MATLAB に詳しくない読者向け: それらがどのファミリに属しているかはわかりませんが、MATLAB 正規表現はここで詳細に説明されています。MATLAB のコメント文字は%(パーセント) で、その文字列区切り文字は'(アポストロフィ) です。文字列内の文字列区切り文字は、二重アポストロフィ ( 'this is how you write "it''s" in a string.') として記述されます。さらに複雑なことに、行列転置演算子アポストロフィ ( A'(エルミート) またはA.'(通常)) です。

ここで、暗い理由 (詳しく説明しません:) のために、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)

だから私はほとんどそこにいますが、まだ完全ではありません:)

残念ながら、私はこれについて考えるのに費やすことができる時間を使い果たし、他のことを続ける必要があるので、おそらくもっと時間のある他の誰かがこれらの質問について考えるのに十分友好的です:

  1. 文字列内のコメント文字は、注意が必要な唯一の例外ですか?
  2. これを行うための正しいおよび/またはより効率的な方法は何ですか?
4

5 に答える 5

4

これは、どの文字が前に許可されているかをチェックすることで、共役転置ケースに一致します。

  1. 数字 2'
  2. 手紙A'
  3. ドットA.'
  4. 左括弧、中括弧と大括弧A(1)'A{1}'および[1 2 3]'

これらは私が今考えることができる唯一のケースです。

C = regexprep(str, '^(([^'']*''[^'']*''|[^'']*[\.a-zA-Z0-9\)\}\]]''[^'']*)*[^'']*)%.*$', '$1')

あなたの例では、それが返されます

>> 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.';'
于 2013-06-28T09:57:17.230 に答える
4

私が見つけたものを見て!:)

Peter J. Acklam によるコメント削除ツールボックス。

m-code の場合、次の正規表現が含まれます。

mainregex = [ ...
     ' (                   ' ... % Grouping parenthesis (content goes to $1).
     '   ( ^ | \n )        ' ... % Beginning of string or beginning of line.
     '   (                 ' ... % Non-capturing grouping parenthesis.
     '                     ' ...
     '' ... % Match anything that is neither a comment nor a string...
     '       (             ' ... % Non-capturing grouping parenthesis.
     '           [\]\)}\w.]' ... % Either a character followed by
     '           ''+       ' ... %    one or more transpose operators
     '         |           ' ... % or else
     '           [^''%]    ' ... %   any character except single quote (which
     '                     ' ... %   starts a string) or a percent sign (which
     '                     ' ... %   starts a comment).
     '       )+            ' ... % Match one or more times.
     '                     ' ...
     '' ...  % ...or...
     '     |               ' ...
     '                     ' ...
     '' ...  % ...match a string.
     '       ''            ' ... % Opening single quote that starts the string.
     '         [^''\n]*    ' ... % Zero or more chars that are neither single
     '                     ' ... %   quotes (special) nor newlines (illegal).
     '         (           ' ... % Non-capturing grouping parenthesis.
     '           ''''      ' ... % An embedded (literal) single quote character.
     '           [^''\n]*  ' ... % Again, zero or more chars that are neither
     '                     ' ... %   single quotes nor newlines.
     '         )*          ' ... % Match zero or more times.
     '       ''            ' ... % Closing single quote that ends the string.
     '                     ' ...
     '   )*                ' ... % Match zero or more times.
     ' )                   ' ...
     ' [^\n]*              ' ... % What remains must be a comment.
              ];

  % Remove all the blanks from the regex.
  mainregex = mainregex(~isspace(mainregex));

になる

mainregex  = '((^|\n)(([\]\)}\w.]''+|[^''%])+|''[^''\n]*(''''[^''\n]*)*'')*)[^\n]*'

として使用する必要があります

C = regexprep(str, mainregex, '$1')

これまでのところ、すべてのテストに耐えているので、これで問題がうまく解決されるはずです:)

于 2013-06-28T14:07:56.657 に答える