2016-05-24 13 views
2

なんらかの理由で、Javaファイル(TagMatchingInterface.javaなど)の内容をスキャンし、正規表現を介してクラス名(TagMatchingInterface)を取得したいが、正規表現が正しくないクラス名いくつかのキーワード(クラス/インタフェース/列挙型)のコメントの中に隠れている:Regexが正しいJavaクラス名を取得する

/** 
* 
* @author XXXX 
* Introduction: A common interface that judges all kinds of algorithm tags. 
* some other comment 
*/ 
public class TagMatchingInterface 
{ 
    // content 
    public class InnerClazz{ 
    // content 
    } 
} 

は、ここに私のパターンです:

public Pattern CLASS_PATTERN = Pattern.compile("(?:public\\s)?(?:.*\\s)?(class|interface|enum)\\s+([$_a-zA-Z][$_a-zA-Z0-9]*)"); 
.... 
Matcher matcher = CLASS_PATTERN.matcher(content); 
if (matcher.find()) { 
    System.out.println(match.group(2)); 
} 

私の正規表現についての任意のアイデア?

+2

なぜ気になるのですか?クラス名はファイル名の右に... – Laurel

+1

*何らかの理由で* **何*理由***? Javaはコンパイルされた言語です。実行時には通常、ソースはありません。 –

+0

MySQLからクラスをロードするために私のカスタムクラスロードを使いたいので、コンテンツを複数行の文字列としてスキャンする必要があります –

答えて

1

説明

(?<=\n|\A)(?:public\s)?(class|interface|enum)\s([^\n\s]*) 

Regular expression visualization

この正規表現は、次のん:

  • 文字列がclassまたはinterfaceまたはenum
  • こと public
  • を開始することができ
  • キャプチャ名

注、私は例

ライブ例

https://regex101.com/r/vR0iK3/1

サンプルテキスト

をグローバルと大文字小文字を区別しないフラグ

を使用することをお勧めします
/** 
* 
* @author XXXX 
* Introduction: A common interface that judges all kinds of algorithm tags. 
* some other comment 
*/ 
public class TagMatchingInterface 
{ 
    // content 
    public class InnerClazz{ 
    // content 
    } 
} 

サンプル

[0][0] = public class TagMatchingInterface 
[0][1] = class 
[0][2] = TagMatchingInterface 

キャプチャグループマッチ:

  • グループ0はマッチ全体
  • グループ1クラス
  • グループ2名
  • を取得し、取得します

説明

NODE      EXPLANATION 
---------------------------------------------------------------------- 
    (?<=      look behind to see if there is: 
---------------------------------------------------------------------- 
    \n      '\n' (newline) 
---------------------------------------------------------------------- 
    |      OR 
---------------------------------------------------------------------- 
    \A      Start of the string 
---------------------------------------------------------------------- 
)      end of look-behind 
---------------------------------------------------------------------- 
    (?:      group, but do not capture (optional 
          (matching the most amount possible)): 
---------------------------------------------------------------------- 
    public     'public' 
---------------------------------------------------------------------- 
    \s      whitespace (\n, \r, \t, \f, and " ") 
---------------------------------------------------------------------- 
)?      end of grouping 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    class     'class' 
---------------------------------------------------------------------- 
    |      OR 
---------------------------------------------------------------------- 
    interface    'interface' 
---------------------------------------------------------------------- 
    |      OR 
---------------------------------------------------------------------- 
    enum      'enum' 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
    \s      whitespace (\n, \r, \t, \f, and " ") 
---------------------------------------------------------------------- 
    (      group and capture to \2: 
---------------------------------------------------------------------- 
    [^\n\s]*     any character except: '\n' (newline), 
          whitespace (\n, \r, \t, \f, and " ") (0 
          or more times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
)      end of \2 
---------------------------------------------------------------------- 
+0

それは動作します!ありがとう、あなたの空想的な絵の答え –

+0

ここにすべての場合にマッチする正規表現 Pattern.compile( "(?<= \\ n | \\ A)(?:\\ s *パブリック\\ s)?\\ s * "+ "(最終\\ s +クラス|最終\\ s +パブリック\\ s +クラス| "+ "抽象的な\\ s +クラス|抽象的な\\ s +パブリック\\ s +クラス| "+ "class |" + "抽象的な\\ s +インターフェース|抽象的な\\ s + public \\ s +インターフェース|" + "インターフェース|" + "enum)\\ s +([$ _ a-zA-Z ] [$ _ a-zA-Z0-9] *) "); –

+0

インデントされている場合、これは 'class'と一致しません。他の[クラス修飾子](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.1)は処理されません。そして、ルック・バックは、 'MULTILINE'フラグと組み合わされた'^'があったはずだったのです。 – MvG

0

...いくつかのキーワード(クラス/インタフェース/列挙型)のコメントに隠れてあります

そして、最初のすべてのコメントを取り除くには。適切な正規表現は、書くのがかなり簡単です。私はあなたが両方の種類のコメント(1行と複数行)を同時に削除することをお勧めします。

クラスの前の注釈に文字列が含まれている可能性があるので、すべての文字列を取り除くこともできます。publicのチェック

"(?:public\\s)?(?:.*\\s)?(class|interface|enum)\\s+([$_a-zA-Z][$_a-zA-Z0-9]*)"

ことのない部分は全く同じように一致しているので、少し目的を果たします。実際にはclass modifiersのいずれかがfinalまたはabstractの場合は、後の部分のみが一致します。public

クラスが実際に公開されているかどうかを知りたい場合は、これらもチェックする必要があります。任意の深さにネストされたカッコで囲まれた引数を持つアノテーションを持つことができるので、難しいでしょう。これは、正規表現が正しく処理できないものです。

nameに非ASCII文字を含むクラスについて教えてください。入力ではunicode escapesはどうですか?

+0

ここに私の正規表現はすべての場合に一致する Pattern.compile( "(?<= \\ n | \\ A)(?:\\ s *パブリック\\ s)?\\ s *" + " + "抽象的な\\ s +クラス|抽象的な\\ s + public \\ s +クラス|" + "クラス|" + "抽象的な\\ s +インターフェイス|抽象的な\\ s + public \\ s +インターフェース" + "インターフェイス|" + "enum)\\ s +([$ _a-zA-Z] [$ _ a- Z0-9] *) "); –

+0

@vash_ace: 'public @Annotated class Foo'をpublicとして報告しません。 – MvG

関連する問題