regulares - Regex que coincidirá con una declaración de método Java
matches java ejemplo (11)
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.
Aquí está mi expresión regular: "/w+ +/w+ */(.*/) */{"
Para aquellos que no saben cómo es un método de Java, les proporcionaré uno básico:
int foo()
{
}
Hay varias partes opcionales para los métodos de 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 describieron Mike y Adkom.
¿Ha considerado la coincidencia de las palabras clave posibles reales? como:
(?:(?:public)|(?:private)|(?:static)|(?:protected)/s+)*
Puede ser un poco más probable que coincida correctamente, aunque también podría hacer que la expresión regular sea más difícil de leer ...
Estoy bastante seguro de que el motor de expresiones regulares de Java es codicioso por defecto, lo que significa que "/w+ +/w+ */(.*/) */{"
Nunca coincidirá ya que el .*
Dentro del paréntesis se comerá todo después del paréntesis de apertura. 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 como la mayoría de las personas realmente no abren los comentarios (sé que con frecuencia no los veo):
Codicioso no 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 ...
Se me ocurrió esto:
/b/w*/s*/w*/(.*?/)/s*/{[/x21-/x7E/s]*/}
Lo probé contra una función de PHP, pero debería funcionar de la misma manera, este es el fragmento de código que 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
Una punta:
Si va a escribir la expresión regular en Perl, use las opciones "xms" para poder dejar espacios y documentar la expresión regular. Por ejemplo, puedes escribir una expresión regular como:
m{/w+ /s+ #return type
/w+ /s* #function name
[(] [^)]* [)] #params
/s* [{] #open paren
}xms
Una de las opciones (pensar x) permite los # 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 habilidad. Si lo hacen, entonces úsenlos.
(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 que incluyen genéricos y matrices son argumentos de devolución, que la expresión regular proporcionada por el autor original no coincide.
Construí un vim regex para hacer esto para ctrlp / funky basado en 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 se ve así en Java:
^/s+(?:</w+>/s+){0,3}(?:[/w/</>/[/]])+/s+/w+/s*/([^/)]*/)(?:/w|/s|/{)+$
Después de mirar a través de las otras respuestas, esto es lo que se me 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]*$
Donde {#insert zJRgx123GenericsNotInGroup}
es igual
`(?:<[?/w/[/] ,.&]+>)|(?:<[^<]*<[?/w/[/] ,.&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?/w/[/] ,.&]+>[^>]*>[^>]*>)`
Limitaciones
- CUALQUIER parámetro puede tener una elipsis: "..." (Java permite solo el último)
- Tres niveles de genéricos anidados como máximo: (
<...<...<...>...>...>
bien,<...<...<...<...>...>...>...>
malo). La sintaxis dentro de los genéricos puede ser muy falsa, y todavía parece estar bien para esta expresión regular. - No requiere espacios entre los tipos y sus genéricos de apertura (opcionales) <''
- Reconoce las clases internas, pero no impide que haya dos puntos uno al lado del otro, como Class. 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). Llame a {#insert zJRgxJavaFuncSigThrSemicOrOpnCrly}
, y obtendrá esto:
^[ /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 sin procesar:
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
También necesitaba una expresión tan regular y se me ocurrió esta solución:
"((public|private|protected|static|final|native|synchronized|abstract|transient)+//s)+[//$_//w//<//>//[//]]*//s+[//$_//w]+//([^//)]*//)?//s*//{?[^//}]*//}?"
Esta gramática y la respuesta de Georgios Gousios han sido útiles para construir la expresión regular.
Encontré útil la respuesta de seba229 , captura la mayoría de los escenarios, pero no los siguientes,
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.
Esto es para un caso de uso más específico, pero es mucho más simple, creo que vale la pena compartirlo. Hice esto para encontrar los métodos de "vacío estático público", es decir, las acciones del controlador de reproducción, y lo hice desde la línea de comandos de Windows / Cygwin, usando grep; ver: https://.com/a/7167115/34806
cat Foobar.java | grep -Pzo ''(?s)public static void.*?/)/s+{''
Las dos últimas entradas de mi salida son las 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) {
(public|private|static|protected) ([A-Za-z0-9<>.]+) ([A-Za-z0-9]+)/(
Además, aquí hay una secuencia de reemplazo que puedes usar en IntelliJ
$1 $2 $3(
Lo uso así:
$1 $2 aaa$3(
al convertir archivos Java a Kotlin para evitar que las funciones que comienzan con "get" se conviertan automáticamente en variables. No funciona con el nivel de acceso "predeterminado", pero yo tampoco uso mucho.