2017-06-08 16 views
0

私はC#で正規表現コードを実装しています。アセンブリ言語の解析Regex

ただし、読みにくいです。 と私は構文取り込むことができませんでした....

// tests 
Regex identifier = new Regex("^[^0-9\t\r\n\\~\\!\\@\\#\\" + 
    "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
    "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ][^\t\r\n\\~\\!\\@\\#\\" + 
    "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
    "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ]*");        // _1234asdvvf or asdfvasdf (0asdfasdf -> X) 

Regex number16 = new Regex("^([0][x][0-9A-Fa-f]*|[0-9a-fA-F]*[h])"); // 0xABCD or ABCDh 
Regex number10 = new Regex("^[1-9][0-9]*");       // 123456 (-> X) 
Regex number8 = new Regex("^[0][0-9]*");       //
Regex string_ = new Regex("^[\"]([^\"\r\n]|[\\][\"])*[\"]");  // "asdfkawer\"asdf\"asdfasdf" 
Regex char_  = new Regex("^[\']([^\'\r\n]|[\\][\'])*[\']");  // 'asdfasdf\'asdfasdf\'asdfadf' 
Regex boolean = new Regex("^(true|false)");       // true or false 
Regex floating = new Regex("^([0]|[1-9][0-9]*)\\.[0-9]*[eE]?[\\+\\-]?[0-9]*[f]?"); // 1234.1234e-45123 or 0.123411234e+1234, 123.1234123e10 
Regex limiter = new Regex("^(public|private|protected|internal)"); 
Regex impls  = new Regex("^(extern|static|virtual|abstract)"); 
Regex whitespace= new Regex("^[\t\r\n ]*"); 
Regex operaters = new Regex("^[\\~\\!\\@\\#\\" + 
    "\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
    "\\'\\\"\\<\\>\\/\\?\\.\\,\\-]"); 

// implements 
Regex assemblyRegex = new Regex("^([a-zA-Z][a-zA-Z0-9]*[\t ]*" + // Opcode + Whitespace 

    "((" + // without Comma + Identifier or Numbers or String 
     "[^0-9\t\r\n\\~\\!\\@\\#\\" + 
     "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
     "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ][^\t\r\n\\~\\!\\@\\#\\" + 
     "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
     "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ]*" + // Identifier 

     "|" + // OR 

     "([0][x][0-9A-Fa-f]*|[0-9a-fA-F]*[h])" + // Hexa number 

     "|" + // OR 

     "[1-9][0-9]*" + // Decimal 

     "|" + // OR 

     "[\"]([^\"\r\n]|[\\][\"])*[\"]" + // String 
    ")" + // generic cases 
    "|" + // OR 
     "(qword|dword|word|byte)?[\\[]" + // qword [ 
    // Comma + Identifier or Numbers 
      "(([^0-9\t\r\n\\~\\!\\@\\#\\" + 
      "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
      "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ][^\t\r\n\\~\\!\\@\\#\\" + 
      "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
      "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ]*" + // Identifier 

      "|" + // OR 

      "([0][x][0-9A-Fa-f]*|[0-9a-fA-F]*[h])" + // Hexa number 

      "|" + // OR 

      "[1-9][0-9]*)" + // Decimal 

      "[\\+\\-\\*\\/\\%]?)*" + // Operators 

     "[\\]]" +       // ] 
    ")[\t ]*" + // DEST 

    "([\\,][\t ]*((" + // Comma + Identifier or Numbers or String 
     "[^0-9\t\r\n\\~\\!\\@\\#\\" + 
     "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
     "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ][^\t\r\n\\~\\!\\@\\#\\" + 
     "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
     "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ]*" + // Identifier 

     "|" + // OR 

     "([0][x][0-9A-Fa-f]*|[0-9a-fA-F]*[h])" + // Hexa number 

     "|" + // OR 

     "[1-9][0-9]*" + // Decimal 

     "|" + // OR 

     "[\"]([^\"\r\n]|[\\][\"])*[\"]" + // String 
    ")" + // generic cases 
    "|" + // OR 
     "(qword|dword|word|byte)?[\\[]" + // qword [ 
      // Comma + Identifier or Numbers 
      "(([^0-9\t\r\n\\~\\!\\@\\#\\" + 
      "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
      "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ][^\t\r\n\\~\\!\\@\\#\\" + 
      "\\$\\%\\^\\&\\*\\(\\)\\+\\|\\\\\\[\\]\\{\\}\\:\\;" + 
      "\\'\\\"\\<\\>\\/\\?\\.\\,\\`\\- ]*" + // Identifier 

      "|" + // OR 

      "([0][x][0-9A-Fa-f]*|[0-9a-fA-F]*[h])" + // Hexa number 

      "|" + // OR 

      "[1-9][0-9]*)" + // Decimal 

      "[\\+\\-\\*\\/\\%]?)*" + // Operators 

     "[\\]]" +       // ] 
    "))*" + // SRCS 

    "[\r\n]?" + // end of line. 
    "|" + // OR 

    "[\r\n\t ]" + // whitespace only. 
    "|" + // OR 

    "[\\;][^\r\n]*[\r\n])*"); // comment line. 


Match match = assemblyRegex.Match("mov eax, 0xabcd\njmp abcdef\ncmp eax, ebx\ncmp a, b"); 
私は正規表現のコードをデバッグすることができますどのように、コード... から単語をキャプチャし、することができますどのように

....

(これは何かを開発するためではなく、ちょうど私の趣味@ _ @)

=>string[] { "mov", "eax", ",", "qword", "[", "esp", "+", "8", "]" }のような結果を得たいです。 しかし、このコードは、構文を検証するためにのみ動作します。 (ただし、repz cmp a, bは認識できません...) 別名、それは私の意図と別のコードでした。私はそれをどこで修正するか分からない。

  1. regexをより簡単にデバッグする方法はありますか?
  2. トークンを抽出する方法はありますか?
  3. 正規表現を書く方が簡単ですか?
+0

https://regex101.comを試しましたか? –

+0

正規表現アナライザ? Expressoを見てください。.NETで書かれています。つまり、.NET Regexの実装を使用しています。http://www.ultrapico.com/expresso.htm –

+1

文法はうまく収まるでしょうか? –

答えて

0

への回答「正規表現を書く方が簡単ですか?」

リテラルなC#文字列の先頭に@を付けてください。バックスラッシュは文字通りそのような文字列の中で取られます。二重引用符は、二重引用符で二重引用符を挿入します。次の文字列は、"\\'\\\"\\<\\>"@"\'\""\<\>"です。

また、正規表現を複雑にするだけで、特に文字クラス内では不要な多くの文字をエスケープしています。多くの文字は、特に構造物のメタ文字としてのみ解釈されます。コメントに記載されているExpressoのような他のツールは、どの文字がエスケープする必要があるかを簡単に特定するのに役立ちます。

たとえば、文字クラス内の以前の文字列は、@"['""<>]"という単純なもので、エスケープする必要はありません。これにより、他のツールとの間でのコピーも非常に簡単になります。他のツールの間で前後にコピーするときに二重引用符を認識する必要がありますが、共有する特定の文字列では、文字クラスに文字を2回指定しても問題ありません。

の回答では、「トークンを抽出する方法はありますか?」

デフォルトでは、括弧のセットは、番号付きのグループに一致するテキストをキャプチャします。 .Net正規表現は、(?<grpName>pattern)のような名前付きキャプチャグループもサポートしています。 match.Group["grpName"]のように、Match.Groupプロパティを使用してそれらにアクセスします。