2008-09-16 4 views
15

J'ai besoin d'une expression rationnelle qui correspond à une déclaration de méthode java. J'en ai trouvé un qui correspondrait à une déclaration de méthode, mais il faut que le crochet d'ouverture de la méthode soit sur la même ligne que la déclaration. Si vous avez des suggestions pour améliorer ma regex ou simplement en avoir une meilleure, veuillez soumettre une réponse.Regex qui correspond à une déclaration de méthode Java

Voici mon regex: "\w+ +\w+ *\(.*\) *\{"

Pour ceux qui ne savent pas ce qu'est une méthode Java semble que je vais fournir une base:

int foo() 
{ 

} 

Il y a plusieurs pièces en option à des méthodes de Java peut être ajouté aussi bien mais ce sont les seules parties qu'une méthode est garantie d'avoir.

Mise à jour: Mon Regex actuel est "\w+ +\w+ *\([^\)]*\) *\{" afin d'éviter la situation décrite par Mike et adkom.

+0

Je ne sais pas ce qu'est une déclaration de méthode Java ressemble à l'esprit fournissant un exemple? – UnkwnTech

Répondre

3

Avez-vous pensé à rechercher les mots-clés possibles? tels que:

(?:(?:public)|(?:private)|(?:static)|(?:protected)\s+)* 

Il pourrait être un peu plus susceptibles de correspondre correctement, mais il pourrait aussi rendre le regex plus difficile à lire ...

+0

Cette regex a fini par correspondre à la signature de toutes les méthodes que j'avais comme System.out.println() au lieu de simplement les déclarations de méthodes. – Anton

+0

Correspond aux variables statiques et ne correspond pas aux méthodes d'étendue de package. – idbrii

+0

Voici une regex plus complète construite sur ce qui précède. IDE remplace "$ 1 $ 2 $ 3 (" et regex (non cité) (public | privé | statique | protégé) ([A-Za-z] +) ([A-Za-z0-9] +) \ ( – user1122069

2

Je suis assez sûr que le moteur de regex Java est gourmand par défaut , ce qui signifie que "\w+ +\w+ *\(.*\) *\{" ne correspondra jamais puisque le .* dans la parenthèse va tout manger après l'ouverture paren. Je vous recommande de remplacer le .* par [^)], de cette façon vous allez sélectionner tous les caractères non fermés.

NOTE: Mike Stone m'a corrigé dans les commentaires, et étant donné que la plupart des gens ne s'ouvrent pas vraiment les commentaires (je sais que je ne les remarque pas souvent):

Greedy ne signifie pas il ne correspondra jamais ... mais il mangera des parens s'il y a plus de parens après pour satisfaire le reste de la regex ... donc par exemple "public void foo (int arg) {if (test) {System.exit (0);}} » ne correspondra pas à bien ...

+0

Greedy doesn ' t signifie qu'il ne sera jamais égal ... mais il mangera des parens s'il y a plus de parens après pour satisfaire le reste de la regex ... donc par exemple "public void foo (int arg) {if (test) {System.exit (0);}} "ne correspondra pas correctement ... –

2

je suis venu avec ceci:

\b\w*\s*\w*\(.*?\)\s*\{[\x21-\x7E\s]*\} 

Je l'ai testé contre une fonction PHP mais il devrait fonctionner même, voici l'extrait de code je:

function getProfilePic($url) 
{ 
    if(@open_image($url) !== FALSE) 
    { 
     @imagepng($image, 'images/profiles/' . $_SESSION['id'] . '.png'); 
     @imagedestroy($image); 
     return TRUE; 
    } 
    else 
    { 
     return FALSE; 
    } 
} 

PLUS D'INFO:

Options: case insensitive 

Assert position at a word boundary «\b» 
Match a single character that is a “word character” (letters, digits, etc.) «\w*» 
    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) «\s*» 
    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
Match a single character that is a “word character” (letters, digits, etc.) «\w*» 
    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
Match the character “(” literally «\(» 
Match any single character that is not a line break character «.*?» 
    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?» 
Match the character “)” literally «\)» 
Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) «\s*» 
    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
Match the character “{” literally «\{» 
Match a single character present in the list below «[\x21-\x7E\s]*» 
    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
    A character in the range between ASCII character 0x21 (33 decimal) and ASCII character 0x7E (126 decimal) «\x21-\x7E» 
    A whitespace character (spaces, tabs, line breaks, etc.) «\s» 
Match the character “}” literally «\}» 


Created with RegexBuddy 
1

Un conseil:

Si vous voulez écrire la regex en Perl, utilisez le "xm" s "options pour que vous puissiez laisser des espaces et documenter l'expression rationnelle. Par exemple, vous pouvez écrire une expression régulière comme:

m{\w+ \s+  #return type 
    \w+ \s*  #function name 
    [(] [^)]* [)] #params 
    \s* [{]   #open paren 
    }xms 

L'une des options (pensez x) permet aux commentaires # à l'intérieur d'une expression rationnelle. Utilisez aussi \ s au lieu d'un "". \ s représente tout caractère "vide". Donc, les onglets correspondent également - ce que vous voulez.En Perl vous n'avez pas besoin d'utiliser//, vous pouvez utiliser {} ou <> ou | |.

Vous ne savez pas si d'autres langues ont cette capacité. Si c'est le cas, veuillez les utiliser.

+0

Y at-il une option similaire dans Java? – Anton

19
(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;]) 

Je pense que l'expression rationnelle ci-dessus peut correspondre à presque toutes les combinaisons possibles de déclarations de méthode Java, même ceux y compris les génériques et les tableaux sont des arguments retour, que l'expression rationnelle fournie par l'auteur original ne correspond pas.

+0

Je pense que cela le ferait.Il exclura également les constructeurs aussi, ce qui est bien :-) –

+1

Quel est le' s "au début pour? Pourquoi quelque chose commencerait par deux espaces? Empêche la correspondance de la portée du paquet sauf si l'indentation est juste – idbrii

+0

La réponse de @ seba229 inclut des mots-clés que le vôtre ne fait pas – Rich

0

J'ai construit un vim regex pour faire ceci pour ctrlp/funky basé sur la réponse de Georgios Gousios.

let regex = '\v^\s+'    " preamble 
    let regex .= '%(<\w+>\s+){0,3}'  " visibility, static, final 
    let regex .= '%(\w|[<>[\]])+\s+' " return type 
    let regex .= '\w+\s*'    " method name 
    let regex .= '\([^\)]*\)'   " method parameters 
    let regex .= '%(\w|\s|\{)+$'  " postamble 

Je suppose que ressemble à ceci en Java:

^\s+(?:<\w+>\s+){0,3}(?:[\w\<\>\[\]])+\s+\w+\s*\([^\)]*\)(?:\w|\s|\{)+$ 
4

J'ai aussi besoin d'une telle expression régulière et est venu avec cette solution:

"((public|private|protected|static|final|native|synchronized|abstract|transient)+\\s)+[\\$_\\w\\<\\>\\[\\]]*\\s+[\\$_\\w]+\\([^\\)]*\\)?\\s*\\{?[^\\}]*\\}?" 

Ce grammar et Georgios La réponse de Gousios a été utile pour construire la regex.

+0

Pourquoi threadsafe dans la regex? Ce n'est pas un modificateur en Java. g à la spécification http://docs.oracle.com/javase/specs/jls/se7/html/jls-18.html et/ou http://docs.oracle.com/javase/tutorial/java/nutsandbolts/ _keywords.html –

+0

Merci pour votre commentaire, j'ai mis à jour la réponse. – sbaltes

3

Après avoir consulté les autres réponses, voici ce que je suis venu avec:

#permission 
    ^[ \t]*(?:(?:public|protected|private)\s+)? 
#keywords 
    (?:(static|final|native|synchronized|abstract|threadsafe|transient|{#insert zJRgx123GenericsNotInGroup})\s+){0,} 
#return type 
    #If return type is "return" then it's actually a 'return funcName();' line. Ignore. 
    (?!return) 
    \b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,})\s+ 
#function name 
    \b\w+\b\s* 
#parameters 
    \(
     #one 
     \s*(?:\b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[]) 
     #two and up 
     \(\s*(?:,\s+\b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])\s*){0,})?\s* 
    \) 
#post parameters 
    (?:\s*throws [\w.]+(\s*,\s*[\w.]+))? 
#close-curly (concrete) or semi-colon (abstract) 
    \s*(?:\{|;)[ \t]*$ 

{#insert zJRgx123GenericsNotInGroup} égal

`(?:<[?\w\[\] ,.&]+>)|(?:<[^<]*<[?\w\[\] ,.&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,.&]+>[^>]*>[^>]*>)` 

Limitations:

  • Tout paramètre peut avoir une ellipse: "..." (Java permet onl y last)
  • Trois niveaux de génériques imbriqués au maximum: (<...<...<...>...>...> correct, <...<...<...<...>...>...>...> mauvais). La syntaxe à l'intérieur des génériques peut être très fausse, et semble toujours correcte à cette regex.
  • Ne nécessite pas d'espace entre les types et leurs génériques (en option) d'ouverture « < »
  • Constate classes internes, mais ne l'empêche pas deux points à côté de l'autre, tels que la classe ....
classe interne

Voici le code PhraseExpress brut (texte automatique et description sur la ligne 1, corps sur la ligne 2). Appelez {#insert zJRgxJavaFuncSigThrSemicOrOpnCrly}, et vous obtenez ceci:

^[ \t]*(?:(?:public|protected|private)\s+)?(?:(static|final|native|synchronized|abstract|threadsafe|transient|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))\s+){0,}(?!return)\b([\w.]+)\b(?:|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))((?:\[\]){0,})\s+\b\w+\b\s*\(\s*(?:\b([\w.]+)\b(?:|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])\s*(?:,\s+\b([\w.]+)\b(?:|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])\s*){0,})?\s*\)(?:\s*throws [\w.]+(\s*,\s*[\w.]+))?\s*(?:\{|;)[ \t]*$ 

Code Raw:

zJRgx123GenericsNotInGroup -- To precede return-type (?:<[?\w\[\] ,.&]+>)|(?:<[^<]*<[?\w\[\] ,.&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,.&]+>[^>]*>[^>]*>) zJRgx123GenericsNotInGroup 
zJRgx0OrMoreParams \s*(?:{#insert zJRgxParamTypeName}\s*(?:,\s+{#insert zJRgxParamTypeName}\s*){0,})?\s* zJRgx0OrMoreParams 
zJRgxJavaFuncNmThrClsPrn_M_fnm -- Needs zvFOBJ_NAME (?<=\s)\b{#insert zvFOBJ_NAME}{#insert zzJRgxPostFuncNmThrClsPrn} zJRgxJavaFuncNmThrClsPrn_M_fnm 
zJRgxJavaFuncSigThrSemicOrOpnCrly -(**)- {#insert zzJRgxJavaFuncSigPreFuncName}\w+{#insert zzJRgxJavaFuncSigPostFuncName} zJRgxJavaFuncSigThrSemicOrOpnCrly 
zJRgxJavaFuncSigThrSemicOrOpnCrly_M_fnm -- Needs zvFOBJ_NAME {#insert zzJRgxJavaFuncSigPreFuncName}{#insert zvFOBJ_NAME}{#insert zzJRgxJavaFuncSigPostFuncName} zJRgxJavaFuncSigThrSemicOrOpnCrly_M_fnm 
zJRgxOptKeywordsBtwScopeAndRetType (?:(static|final|native|synchronized|abstract|threadsafe|transient|{#insert zJRgx123GenericsNotInGroup})\s+){0,} zJRgxOptKeywordsBtwScopeAndRetType 
zJRgxOptionalPubProtPriv (?:(?:public|protected|private)\s+)? zJRgxOptionalPubProtPriv 
zJRgxParamTypeName -(**)- Ends w/ '\b(?![>\[])' to NOT find <? 'extends XClass'> or ...[]> (*Original: zJRgxParamTypeName, Needed by: zJRgxParamTypeName[4FQPTV,ForDel[NmsOnly,Types]]*){#insert zJRgxTypeW0123GenericsArry}(\.\.\.)?\s+(\w+)\b(?![>\[]) zJRgxParamTypeName 
zJRgxTypeW0123GenericsArry -- Grp1=Type, Grp2='[]', if any \b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,}) zJRgxTypeW0123GenericsArry 
zvTTL_PRMS_stL1c {#insert zCutL1c}{#SETPHRASE -description zvTTL_PRMS -content {#INSERTCLIPBOARD} -autotext zvTTL_PRMS -folder ctvv_folder} zvTTL_PRMS_stL1c 
zvTTL_PRMS_stL1cSvRstrCB {#insert zvCB_CONTENTS_stCB}{#insert zvTTL_PRMS_stL1c}{#insert zSetCBToCB_CONTENTS} zvTTL_PRMS_stL1cSvRstrCB 
zvTTL_PRMS_stPrompt {#SETPHRASE -description zvTTL_PRMS -content {#INPUT -head How many parameters? -single} -autotext zvTTL_PRMS -folder ctvv_folder} zvTTL_PRMS_stPrompt 
zzJRgxJavaFuncNmThrClsPrn_M_fnmTtlp -- Needs zvFOBJ_NAME, zvTTL_PRMS (?<=[ \t])\b{#insert zvFOBJ_NAME}\b\s*\(\s*{#insert {#COND -if {#insert zvTTL_PRMS} = 0 -then z1slp -else zzParamsGT0_M_ttlp}}\) zzJRgxJavaFuncNmThrClsPrn_M_fnmTtlp 
zzJRgxJavaFuncSigPostFuncName {#insert zzJRgxPostFuncNmThrClsPrn}(?:\s*throws \b(?:[\w.]+)\b(\s*,\s*\b(?:[\w.]+)\b))?\s*(?:\{|;)[ \t]*$ zzJRgxJavaFuncSigPostFuncName 
zzJRgxJavaFuncSigPreFuncName (*If a type has generics, there may be no spaces between it and the first open '<', also requires generics with three nestings at the most (<...<...<...>...>...> okay, <...<...<...<...>...>...>...> not)*)^[ \t]*{#insert zJRgxOptionalPubProtPriv}{#insert zJRgxOptKeywordsBtwScopeAndRetType}(*To prevent 'return funcName();' from being recognized:*)(?!return){#insert zJRgxTypeW0123GenericsArry}\s+\b zzJRgxJavaFuncSigPreFuncName 
zzJRgxPostFuncNmThrClsPrn \b\s*\({#insert zJRgx0OrMoreParams}\) zzJRgxPostFuncNmThrClsPrn 
zzParamsGT0_M_ttlp -- Needs zvTTL_PRMS {#insert zJRgxParamTypeName}\s*{#insert {#COND -if {#insert zvTTL_PRMS} = 1 -then z1slp -else zzParamsGT1_M_ttlp}} zzParamsGT0_M_ttlp 
zzParamsGT1_M_ttlp {#LOOP ,\s+{#insert zJRgxParamTypeName}\s* -count {#CALC {#insert zvTTL_PRMS} - 1 -round 0 -thousands none}} zzParamsGT1_M_ttlp 
+0

Avoir à donner des accessoires à RegexBuddy pour m'aider à travailler à travers ce: http://www.regexbuddy.com/ – aliteralmind

0

Ceci est un cas d'utilisation plus spécifique, mais il est tellement plus simple, je crois que son partage de la valeur. Je l'ai fait pour trouver des méthodes de «vide statique public», c'est-à-direJouer les actions du contrôleur, et je l'ai fait à partir de la ligne de commande Windows/Cygwin, en utilisant grep; voir: https://stackoverflow.com/a/7167115/34806

cat Foobar.java | grep -Pzo '(?s)public static void.*?\)\s+{' 

Les deux dernières entrées de ma sortie sont les suivantes:

public static void activeWorkEventStations (String type, 
      String symbol, 
      String section, 
      String day, 
      String priority, 
      @As("yyyy-MM-dd") Date scheduleDepartureDate) { 
public static void getActiveScheduleChangeLogs(String type, 
      String symbol, 
      String section, 
      String day, 
      String priority, 
      @As("yyyy-MM-dd") Date scheduleDepartureDate) { 
0

Je trouve seba229 « s réponse utile, il capture la plupart des scénarios, mais pas les éléments suivants,

public <T> T name(final Class<T> x, final T y) 

Cette regex capturera cela aussi.

((public|private|protected|static|final|native|synchronized|abstract|transient)+\s)+[\$_\w\<\>\w\s\[\]]*\s+[\$_\w]+\([^\)]*\)?\s* 

Espérons que cela aide.

0
(public|private|static|protected) ([A-Za-z0-9<>.]+) ([A-Za-z0-9]+)\(

De plus, voici une remplacer séquence que vous pouvez utiliser dans IntelliJ

$1 $2 $3(

Je l'utilise comme ceci:

$1 $2 aaa$3(

lors de la conversion des fichiers Java à Kotlin pour éviter les fonctions qui commencent par "get" de devenir automatiquement des variables. Ne fonctionne pas avec le niveau d'accès "par défaut", mais je n'utilise pas beaucoup de moi-même.

0

(public|private|static|protected|abstract|native|synchronized) +([a-zA-Z0-9<>._?, ]+) +([a-zA-Z0-9_]+) *\\([a-zA-Z0-9<>\\[\\]._?, \n]*\\) *([a-zA-Z0-9_ ,\n]*) *\\{

Le Regex ci-dessus détecte toutes les définitions possibles de la méthode java. Testé sur beaucoup de fichiers de code source. Pour inclure les constructeurs et utiliser le ci-dessous regex:

(public|private|static|protected|abstract|native|synchronized) +([a-zA-Z0-9<>._?, ]*) +([a-zA-Z0-9_]+) *\\([a-zA-Z0-9<>\\[\\]._?, \n]*\\) *([a-zA-Z0-9_ ,\n]*) *\\{

Questions connexes