¿Cómo uso una expresión regular de Python para que coincida con la syntax de la función de MATLAB?

Estoy tratando de encontrar todas las entradas / salidas de todas las funciones de MATLAB en nuestra biblioteca interna. Soy nuevo (por primera vez) en expresiones regulares y he estado tratando de usar el modo multilínea en la biblioteca de re de Python.

La syntax de la función MATLAB se ve así:

 function output = func_name(input) 

donde la firma puede abarcar múltiples lineas.

Comencé con un patrón como:

 re.compile(r"^.*function (.*)=(.*)\([.\n]*\)$", re.M) 

pero sigo recibiendo un error de operador de plantilla no compatible. Cualquier puntero es apreciado!

EDITAR:

Ahora tengo:

 pattern = re.compile(r"^\s*function (.*?)= [\w\n.]*?\(.*?\)", re.M|re.DOTALL) 

que da partidos como:

  function [fcst, spread] = ... VolFcstMKT(R,... mktVol,... calibrate,... spread_init,... fcstdays,... tsperyear) if(calibrate) if(nargin < 6) tsperyear = 252; end templen = length(R) 

Mi pregunta es ¿por qué da las líneas adicionales en lugar de detenerse en la primera?

El error peculiar (interno) que está recibiendo debería aparecer si pasa re.T lugar de re.M como el segundo argumento para re.compile ( re.template – una entrada actualmente no documentada – es la intención de usarlo y, en resumen, los RE de la plantilla no admiten repetición o retroceso). ¿Puede print re.M para mostrar cuál es el valor de su código antes de llamar a re.compile ?

Una vez que se haya solucionado, podemos discutir los detalles de tu RE deseada (en resumen: si la parte de input puede incluir paréntesis, estás fuera de suerte, de lo contrario re.DOTALL y alguna reescritura de tu patrón deberían ser de ayuda), pero corregir esto es extraño La ocurrencia de un error interno parece tener prioridad.

Editar : con este error diagnosticado (según los comentarios debajo de esta Q), pasar a la pregunta actual del OP: re.DOTALL|re.MULTINE , más el ‘$’ al final del patrón, más el codicioso en todas partes coincidencias (usando .* , en lugar de .*? para no codiciosos), todos juntos aseguran que si coinciden las expresiones regulares coincidirá con una franja lo más amplia posible … eso es exactamente lo que está pidiendo este combo. Probablemente sea mejor abrir otra Q con un ejemplo específico: cuál es la entrada, qué se compara, qué le gustaría que coincidiera con la expresión regular, etc.

Aquí hay una expresión regular que debe coincidir con cualquier statement de función de MATLAB al inicio de un archivo-m:

 ^\s*function\s+((\[[\w\s,.]*\]|[\w]*)\s*=)?[\s.]*\w+(\([^)]*\))? 

Y aquí hay una explicación más detallada de los componentes:

 ^\s* # Match 0 or more whitespace characters # at the start function # Match the word function \s+ # Match 1 or more whitespace characters ( # Start grouping 1 ( # Start grouping 2 \[ # Match opening bracket [\w\s,.]* # Match 0 or more letters, numbers, # whitespace, underscores, commas, # or periods... \] # Match closing bracket |[\w]* # ... or match 0 or more letters, # numbers, or underscores ) # End grouping 2 \s* # Match 0 or more whitespace characters = # Match an equal sign )? # End grouping 1; Match it 0 or 1 times [\s.]* # Match 0 or more whitespace characters # or periods \w+ # Match 1 or more letters, numbers, or # underscores ( # Start grouping 3 \( # Match opening parenthesis [^)]* # Match 0 or more characters that # aren't a closing parenthesis \) # Match closing parenthesis )? # End grouping 3; Match it 0 or 1 times 

Ya sea que utilice expresiones regulares o operaciones de cadena básicas, debe tener en cuenta las diferentes formas que puede tomar la statement de función en MATLAB. La forma general es:

 function [out1,out2,...] = func_name(in1,in2,...) 

Específicamente, usted podría ver cualquiera de las siguientes formas:

 function func_name %# No inputs or outputs function func_name(in1) %# 1 input function func_name(in1,in2) %# 2 inputs function out1 = func_name %# 1 output function [out1] = func_name %# Also 1 output function [out1,out2] = func_name %# 2 outputs ... 

También puede tener continuaciones de línea ( ... ) en muchos puntos, como después del signo igual o dentro de la lista de argumentos:

 function out1 = ... func_name(in1,... in2,... in3) 

También es posible que desee tener en cuenta factores como las listas de argumentos de entrada variable y los argumentos de entrada ignorados :

 function func_name(varargin) %# Any number of inputs possible function func_name(in1,~,in3) %# Second of three inputs is ignored 

Por supuesto, muchos archivos m contienen más de 1 función, por lo que tendrá que decidir cómo tratar con las subfunciones , las funciones anidadas y las funciones potencialmente anónimas (que tienen una syntax de statement diferente).

¿qué hay de las operaciones de cadena de Python normales? Solo un ejemplo solo

 for line in open("file"): sline=line.strip() if sline.startswith("function"): lhs,rhs =sline.split("=") out=lhs.replace("function ","") if "[" in out and "]" in out: out=out.replace("]","").replace("[","").split(",") print out m=rhs.find("(") if m!=-1: rhs=rhs[m:].replace(")","").replace("(","").split(",") print rhs 

ejemplo de salida

 $ cat file function [mean,stdev] = stat(x) n = length(x); mean = sum(x)/n; stdev = sqrt(sum((x-mean).^2/n)); function mean = avg(x,n) mean = sum(x)/n; $ python python.py ['mean', 'stdev '] [' statx'] mean [' avgx', 'n'] 

Por supuesto, debería haber muchos otros escenarios de statement de funciones en Matlab, como function nothing function a = b , function a = b , etc., así que agregue esos controles usted mismo.