Question

J'ai besoin d'un regex qui corresponde à une déclaration de méthode java. J'en ai trouvé un qui correspondra à 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 mon expression rationnelle ou si vous en avez simplement une meilleure, merci de soumettre une réponse.

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

Pour ceux qui ne savent pas à quoi ressemble une méthode Java, je vais en fournir une de base:

int foo()
{

}

Plusieurs méthodes facultatives peuvent être ajoutées aux méthodes java, mais ce sont les seules parties qu'une méthode est sûre de posséder.

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

Était-ce utile?

La solution

Avez-vous envisagé de faire correspondre les mots clés possibles? tels que:

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

Cela pourrait être un peu plus susceptible de correspondre correctement, bien que cela puisse également rendre la regex plus difficile à lire ...

Autres conseils

(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éthodes Java, même celles comprenant des génériques et des tableaux sont des arguments de retour, auxquels l'expression rationnelle fournie par l'auteur original ne correspondait pas.

Après avoir parcouru les autres réponses, voici ce que j’ai trouvé:

#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} est égal à

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

Limitations:

  • N'IMPORTE QUEL paramètre peut avoir des points de suspension: " ... " (Java ne permet que le dernier)
  • Trois niveaux de génériques imbriqués au plus: (<...<...<...>...>...> ok, <...<...<...<...>...>...>...> mauvais). La syntaxe à l'intérieur des génériques peut être très fausse, et semble toujours convenir à cette regex.
  • N'exige aucun espace entre les types et leurs génériques d'ouverture (facultatif) '<'
  • Reconnaît les classes internes, mais n'empêche pas deux points l'un à côté de l'autre, tels que Class .... InnerClass

Le code PhraseExpress brut est présenté ci-dessous (texte automatique et description à la ligne 1, corps à 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 brut:

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

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

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

Ces grammaire et la réponse de Georgios Gousios ont été utiles pour construire le regex.

Je suis à peu près sûr que le moteur des expressions rationnelles de Java est glouton par défaut, ce qui signifie que "\w+ +\w+ *\(.*\) *\{" ne correspondra jamais, car le .* contenu dans la parenthèse mange tout après le paren d'ouverture. Je vous recommande de remplacer le <=> par [^)]. Ainsi, tous les caractères non-fermants seront sélectionnés.

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

  

Gourmand ne veut pas dire que ça ne marchera jamais ... mais il mangera des parens s’il ya plus de parens après pour satisfaire le reste de la regex ... ainsi, par exemple & "public void foo (int arg ) {if (test) {System.exit (0); }} " ne correspondra pas correctement ...

Je suis arrivé avec ceci:

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

Je l'ai testé par rapport à une fonction PHP, mais cela devrait fonctionner de la même manière. Il s'agit de l'extrait de code que j'ai utilisé:

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

Un conseil:

Si vous allez écrire l'expression rationnelle en Perl, utilisez le & "; xms &"; options afin que vous puissiez laisser des espaces et documenter la regex. Par exemple, vous pouvez écrire une regex comme:

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

Une des options (think x) permet le nombre de commentaires dans une regex. Utilisez également \ s au lieu de & Quot; & \ s signifie & "; vide &"; personnage. Ainsi, les onglets correspondraient également - ce que vous voudriez. En Perl, vous n'avez pas besoin d'utiliser / /, vous pouvez utiliser {} ou & Lt; > ou | |.

Je ne sais pas si d'autres langues ont cette capacité. S'ils le font, alors s'il vous plaît, utilisez-les.

(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]*) *\\{

La regex ci-dessus détectera toutes les définitions de méthodes java possibles. Testé sur beaucoup de fichiers de code source. Pour inclure également les constructeurs, utilisez la regex ci-dessous:

(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]*) *\\{

Ceci choisira le nom de la méthode et non la ligne entière.

(?<=public static void )\w+|(?<=private static void )\w+|(?<=protected static void )\w+|(?<=public void )\w+|(?<=private void )\w+|(?<=protected void )\w+|(?<=public final void)\w+|(?<=private final void)\w+|(?<=protected final void)\w+|(?<=private void )\w+|(?<=protected void )\w+|(?<=public static final void )\w+|(?<=private static final void )\w+|(?<=public final static void )\w+|(?<=protected final static void )\\w+|(?<=private final static void )\w+|(?<=protected final static void )\w+|(?<=void )\w+|(?<=private static )\w+

J'ai créé une regex vim pour ce faire pour ctrlp / funky d'après 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 cela ressemble à ceci en Java:

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

Ceci est destiné à un cas d'utilisation plus spécifique, mais il est tellement plus simple que cela vaut la peine d'être partagé. Je l’ai fait pour trouver les méthodes de «vide statique public», c’est-à-dire les actions du contrôleur de lecture, 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) {

J'ai trouvé la réponse de seba229 utile, elle capture la plupart des scénarios, mais pas les suivants,

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

Cette expression rationnelle capturera cela également.

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

J'espère que cela vous aidera.

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

En outre, voici une séquence de remplacement que vous pouvez utiliser dans IntelliJ

$1 $2 $3(

Je l'utilise comme ceci:

$1 $2 aaa$3(

lors de la conversion de fichiers Java en Kotlin pour empêcher les fonctions commençant par " obtenir " de se transformer automatiquement en variables. Ne fonctionne pas avec & Quot; défaut & Quot; niveau d'accès, mais je ne l'utilise pas beaucoup moi-même.

À compter de la version 2.19.0, le a été construit. -in dans une expression rationnelle pour Java semble maintenant bien fonctionner, il ne sera donc peut-être pas nécessaire de fournir le vôtre.

"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
"^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$"

(La première ligne semble être pour filtrer les lignes qui ressemblent à des déclarations de méthode mais ne le sont pas.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top