2016-03-22 15 views
8

Ho cercato di scrivere un'espressione regolare per abbinare le importazioni di una classe. Lasciate che la classe siaRegex corrispondente alle importazioni di una classe

import static org.junit.Assert.*; 
import org. 
     package. 
     Test; 
import mypackage.mystuff; 

L'uscita dovrebbe essere [org.junit.Assert. *, Org.package.Test, mypackage.mystuff]. Ho avuto problemi con le interruzioni di riga e con le espressioni regolari in generale, dal momento che non sono così esperto con loro. Questo è il mio tentativo di corrente:

((?<=\bimport\s)\s*([^\s]+)*([a-z.A-Z0-9]+.(?=;))) 

risposta

4

Questa regex dovrebbe funzionare per tutti i tipi di istruzioni di importazione e non deve corrispondere dichiarazioni non valide: import\p{javaIdentifierIgnorable}*\p{javaWhitespace}+(?:static\p{javaIdentifierIgnorable}*\p{javaWhitespace}+)?(\p{javaJavaIdentifierStart}[\p{javaJavaIdentifierPart}\p{javaIdentifierIgnorable}]*(?:\p{javaWhitespace}*\.\p{javaWhitespace}*\*|(?:\p{javaWhitespace}*\.\p{javaWhitespace}*\p{javaJavaIdentifierStart}[\p{javaJavaIdentifierPart}\p{javaIdentifierIgnorable}]*)+(?:\p{javaWhitespace}*\.\p{javaWhitespace}*\*)?))\p{javaWhitespace}*;

E 'ampiamente utilizzando Java's categories, per esempio \p{javaWhitespace} chiamate Character.isWhitespace:

Categorie che si comportano come i java.lang.Character booleane ismethodname metodi (ad eccezione di quelli deprecato) sono disponibili attraverso lo stesso \p{prop} sintassi in cui la proprietà specificata ha il nome javamethodname.

Ancora non leggibile? IndovinatoÈ per questo che ho cercato di esprimere con il codice Java (REGEX):

public class ImportMatching { 
    static final String IMPORTS = "import\n" + 
     "java.io.IOException;\n" + 
     "import java.nio.file.Files;\n" + 
     "import java . nio . file. Path;\n" + 
     "import java.nio.file.Paths\n" + 
     ";import java.util.ArrayList;\n" + 
     "import static java.util. List.*;\n" + 
     "import java.util.List. *;\n" + 
     "import java.\n" + 
     "  util.\n" + 
     "  List;\n" + 
     " import java.util.regex.Matcher;import java.util.regex.Pattern\n" + 
     "   ;\n" + 
     "import mypackage.mystuff;\n" + 
     "import mypackage.*;"; 
    static final String WS = "\\p{javaWhitespace}"; 
    static final String IG = "\\p{javaIdentifierIgnorable}"; 
    static final String ID = "\\p{javaJavaIdentifierStart}" + multiple(charClass("\\p{javaJavaIdentifierPart}" + IG)); 
    static final String DOT = multiple(WS) + "\\." + multiple(WS); 
    static final String WC = "\\*"; 
    static final String REGEX = "import" + multiple(IG) + atLeastOnce(WS) + 
     optional(nonCapturingGroup("static" + multiple(IG) + atLeastOnce(WS))) + 
     group(
      ID + 
      nonCapturingGroup(
       or(
        DOT + WC, 
        atLeastOnce(nonCapturingGroup(DOT + ID)) + optional(nonCapturingGroup(DOT + WC)) 
       ) 
      ) 
     ) + 
     multiple(WS) + ';'; 

    public static void main(String[] args) { 
     final List<String> imports = getImports(IMPORTS); 
     System.out.printf("Matches: %d%n", imports.size()); 
     imports.stream().forEach(System.out::println); 
    } 

    static List<String> getImports(String javaSource) { 
     Pattern pattern = Pattern.compile(REGEX); 
     Matcher matcher = pattern.matcher(javaSource); 
     List<String> imports = new ArrayList<>(); 
     while(matcher.find()) { 
      imports.add(matcher.group(1).replaceAll(charClass(WS + IG), "")); 
     } 
     return imports; 
    } 

    static String nonCapturingGroup(String regex) { 
     return group("?:" + regex); 
    } 

    static String or(String option1, String option2) { 
     return option1 + '|' + option2; 
    } 

    static String atLeastOnce(String regex) { 
     return regex + '+'; 
    } 

    static String optional(String regex) { 
     return regex + '?'; 
    } 

    static String multiple(String regex) { 
     return regex + '*'; 
    } 

    static String group(String regex) { 
     return '(' + regex + ')'; 
    } 

    static String charClass(String regex) { 
     return '[' + regex + ']'; 
    } 
} 

che sto utilizzando un gruppo per la parte package.Class e quindi sostituire qualsiasi rumore dalle corrispondenze.

L'ingresso di test è la seguente stringa (IMPORTS):

import 
java.io.IOException; 
import java.nio.file.Files; 
import java . nio . file. Path; 
import java.nio.file.Paths 
;import java.util.ArrayList; 
import static java.util. List.*; 
import java.util.List. *; 
import java. 
     util. 
     List; 
import java.util.regex.Matcher;import java.util.regex.Pattern 
     ; 
import mypackage.mystuff; 
import mypackage.*; 

L'output:

 
Matches: 12 
java.io.IOException 
java.nio.file.Files 
java.nio.file.Path 
java.nio.file.Paths 
java.util.ArrayList 
java.util.List.* 
java.util.List.* 
java.util.List 
java.util.regex.Matcher 
java.util.regex.Pattern 
mypackage.mystuff 
mypackage.* 
+0

Questo è sorprendente. Grazie! – voskart

0

Prova questa regexp:

import (static)*([^;])*

+0

purtroppo questo non filtra il "importazione statica" nella prima linea – voskart

+0

@voskart , Ho corretto – Alexey

9

Questo (quasi) adatto alle vostre esigenze:

(?<=import (?:static)?+)[^;]+ 

Regular expression visualization

Debuggex Demo

Quasi perché le partite includono le nuove linee, se presenti (ad es. nella tua dichiarazione org.package.Test). Questo dovrebbe essere gestito in seguito:

Pattern pattern = Pattern.compile("(?<=import (?:static)?+)[^;]+"); 
Matcher matcher = pattern.matcher(s); 
while (matcher.find()) { 
    String match = matcher.group().replaceAll("\\s+", ""); 
    // do something with match 
} 

In Java, \s matches [ \t\n\x0B\f\r]. Dai uno sguardo allo possessive quantifiers per capire il quantificatore ?+.

3

È possibile utilizzare questa espressione regolare:

(\w+\.\n*\s*)+([\w\*]+)(?=\;) 

con escape per Java:

(\\w+\\.\\n*\\s*)+([\\w\\*]+)(?=\\;) 

enter image description here

Ecco un tester regex link

1

Forse questo è ciò che si stanno cercando ?

(?<=\bimport)(\s*\R*\s*(?:[a-z0-9A-Z]+(\R|\s)+)*)((([a-zA-Z0-9]+\.)+)[a-zA-Z0-9]*\*?); 

Source

+0

Grazie funziona, brso05 era un po 'più veloce – voskart