2008-09-16 15 views
15

Necesito una Regex que coincida con una declaración de método java. He encontrado uno que coincidirá con una declaración de método, pero requiere que el corchete de apertura del método esté en la misma línea que la declaración. Si tiene alguna sugerencia para mejorar mi expresión regular o simplemente tiene una mejor, envíe una respuesta.Regex que coincidirá con una declaración de método Java

Aquí es mi expresión regular: "\w+ +\w+ *\(.*\) *\{"

Para aquellos que no saben lo que parece un método Java que voy a proporcionar una básica uno:

int foo() 
{ 

} 

Hay varias piezas opcionales a métodos Java que se pueden agregar también, pero esas son las únicas partes que se garantiza que tiene un método.

Actualización: Mi Regex actual es "\w+ +\w+ *\([^\)]*\) *\{" para evitar la situación que describen Mike y Adkom.

+0

No sé lo que es una declaración de método Java se parece a la mente proporcionando un ejemplo? – UnkwnTech

Respuesta

3

¿Ha considerado concordar las palabras clave posibles actuales? tales como:

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

Podría ser un poco más probable que coincida correctamente, aunque también podría hacer que la expresión regular más difícil de leer ...

+0

Esa expresión regular terminó haciendo coincidir la firma de todos los métodos que tenía, como System.out.println() en lugar de solo las declaraciones de métodos. – Anton

+0

Coincide con las variables estáticas y no coincide con los métodos de alcance del paquete. – idbrii

+0

Here'a una regex completa construida de arriba. IDE reemplace "$ 1 $ 2 $ 3 (" y regex (sin comillas) (público | privado | estático | protegido) ([A-Za-z] +) ([A-Za-z0-9] +) \ ( – user1122069

2

Estoy bastante seguro de motor de expresiones regulares de Java es codicioso por defecto , lo que significa que "\w+ +\w+ *\(.*\) *\{" nunca coincidirá ya que .* dentro del paréntesis se comerá todo después de la apertura paren. Le recomiendo que reemplace el .* con [^)], de esta manera seleccionará todos los caracteres que no sean de cierre-paren.

NOTA: Mike Stone me corrigió en los comentarios, y puesto que la mayoría de la gente realmente no abren los comentarios (sé que con frecuencia no se dan cuenta de ellos):

Greedy no significa nunca coincidirá ... pero comerá parens si hay más parens luego de satisfacer el resto de la expresión regular ... así que por ejemplo "public void foo (int arg) {if (test) {System.exit (0);}}" no coincidirá correctamente ...

+0

codicioso doesn ' Esto significa que nunca coincidirá ... pero comerá parens si hay más parens luego de satisfacer el resto de la expresión regular ... así que por ejemplo "public void foo (int arg) {if (test) {System.exit (0);}} "no coincidirá correctamente ... –

2

me ocurrió esto:

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

he comprobado en contra de una función de PHP pero debería funcionar de la misma manera, este es el fragmento de código utilicé:

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

MÁS INFORMACIÓN:

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 consejo:

Si va a escribir la expresión regular en Perl, utilice la "xm s "opciones para que pueda dejar espacios y documentar la expresión regular. Por ejemplo, puede escribir una expresión regular como:

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

Una de las opciones (piensa x) permite el # comentarios dentro de una expresión regular. También use \ s en lugar de un "". \ s representa cualquier caracter "en blanco". Así que las pestañas también coincidirían, que es lo que querrías.En Perl no necesita usar//, puede usar {} o <> o | |

No estoy seguro si otros idiomas tienen esta capacidad. Si lo hacen, entonces úsenlos.

+0

¿hay una opción similar en java? – Anton

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

creo que la expresión regular anterior puede coincidir con casi todas las combinaciones posibles de declaraciones de métodos de Java, incluso aquellos incluidos los medicamentos genéricos y los arreglos son argumentos de retorno, que la expresión regular proporcionada por el autor original no coinciden.

+0

Creo que eso también lo hará. También excluirá a los constructores, lo cual es bueno :-) –

+1

¿Qué es el' \ s 'al principio para? ¿Por qué algo comenzaría con dos espacios? Evita que coincida con el alcance del paquete a menos que la sangría sea la correcta. – idbrii

+0

La respuesta de @seba229 incluye algunas palabras clave que la suya no – Rich

0

Creé un vim regex para hacer esto para ctrlp/funky según la respuesta 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 

supongo que tiene este aspecto en Java:

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

También necesitaba una expresión tan regular y se acercó con esta solución:

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

Este grammar y Georgios La respuesta de Gousios ha sido útil para construir la expresión regular.

+0

¿Por qué es threadsafe en la expresión regular? No es un modificador en Java. g en la especificación http://docs.oracle.com/javase/specs/jls/se7/html/jls-18.html y/o http://docs.oracle.com/javase/tutorial/java/nutsandbolts/ _keywords.html –

+0

Gracias por su comentario, actualicé la respuesta. – sbaltes

3

Después de mirar a través de las otras respuestas, esto es lo que ocurrió:

#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]*$ 

Dónde {#insert zJRgx123GenericsNotInGroup} es igual a

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

Limitaciones:

  • cualquier parámetro puede tener una elipsis: "..." (Java permite onl y última)
  • Tres niveles de genéricos anidados como máximo: (<...<...<...>...>...> está bien, <...<...<...<...>...>...>...> malo). La sintaxis dentro de los genéricos puede ser muy falsa, y todavía parece estar bien para esta expresión regular.
  • Requiere sin espacios entre tipos y sus (opcional) genéricos de apertura '<'
  • Reconoce clases internas, pero no impide que dos puntos junto a la otra, como la clase .... InnerClass

A continuación se muestra el código en bruto de PhraseExpress (auto-texto y descripción en la línea 1, cuerpo en la línea 2). {#insert zJRgxJavaFuncSigThrSemicOrOpnCrly} llamar, y se obtiene lo siguiente:

^[ \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]*$ 

código prima:

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

Tengo que darle apoyo a RegexBuddy por ayudarme a superar esto: http://www.regexbuddy.com/ – aliteralmind

0

Se trata de un caso de uso más específico, pero es mucho más simple que creo compartir su pena. Hice esto para encontrar métodos de "vacío público estático", es decirJuega acciones de controlador, y lo hice desde la línea de comando de Windows/Cygwin, usando grep; ver: https://stackoverflow.com/a/7167115/34806

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

Las dos últimas entradas de mi salida son los siguientes:

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

He encontrado seba229 's respuesta útil, que capta la mayor parte de los escenarios, pero no el siguiente,

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

Esta expresión regular capturará eso también.

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

Espero que esto ayude.

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

Además, aquí es una secuencia de sustitución que puede utilizar en IntelliJ

$1 $2 $3(

lo uso como esto:

$1 $2 aaa$3(

al convertir archivos de Java para Kotlin para evitar funciones que comienzan con "get" se convierte automáticamente en variables. No funciona con el nivel de acceso "predeterminado", pero yo tampoco uso mucho.

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

la expresión regular anteriormente detectará todas las posibles definiciones de método Java. Probado en muchos archivos de código fuente. Para incluir constructores, así utilizar el siguiente expresión regular:

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

Cuestiones relacionadas