Uso de python para dividir una cadena con un delimitador, mientras se ignora el delimitador y escapa las comillas entre comillas

Estoy tratando de dividir una cadena en función de la ubicación de un delimitador (estoy tratando de eliminar los comentarios del código de Fortran). Puedo dividir usando ! en la siguiente cadena:

 x = '''print "hi!" ! Remove me''' pattern = '''(?:[^!"]|"[^"]*")+''' y = re.search(pattern, x) 

Sin embargo, esto falla si la cadena contiene comillas de escape, por ejemplo

 z = '''print "h\"i!" ! Remove me''' 

¿Se puede modificar la expresión regular para manejar citas de escape? ¿O no debería usar expresiones regulares para este tipo de problema?

Aquí hay una expresión regular probada (de Mastering Regular Expressions ) para hacer coincidir los literales de cadena con comillas dobles que pueden contener comillas con barra invertida:

 r'"[^"\\]*(?:\\.[^"\\]*)*"' 

Dentro de las comillas de delimitación, consume cualquier par de caracteres que comience con una barra invertida sin molestarse en identificar el segundo carácter; eso le permite manejar barras diagonales escapadas y otras secuencias de escape sin complicaciones adicionales. También es tan eficiente como puede ser en ausencia de cuantificadores posesivos y grupos atómicos , que no son compatibles con Python.

El regex completo para su aplicación sería:

 r'^((?:[^!"]+|"[^"\\]*(?:\\.[^"\\]*)*")*)!.*$' 

Esto coincide solo con las líneas que contienen comentarios, y captura todo lo que precede al comentario en el grupo # 1. La captura puede ser de longitud cero, para líneas que comienzan con ! . Esta expresión regular está diseñada para usarse con sub lugar de search , como se muestra aquí:

 import re pattern = r'^((?:[^!"]+|"[^"\\]*(?:\\.[^"\\]*)*")*)!.*$' x = '''print "hi!" ! Remove me''' y = re.sub(pattern, r'\1', x) print(y) 

Véalo en acción en ideone.com.

NEGACIÓN DE RESPONSABILIDAD: esta respuesta no es sobre FORTRAN, sino sobre el código que sigue las reglas especificadas en la pregunta. Nunca he trabajado con FORTRAN, y cada referencia que he encontrado en la última hora parece describir un lenguaje completamente diferente. Meh

El análisis de Fortran es en realidad bastante complicado (ver, por ejemplo, un hilo aquí ). No estoy familiarizado con los detalles de la syntax, y donde ‘!’ puede ocurrir. Así que aquí hay un pensamiento: ¿qué tan probable es que los comentarios incluyan ‘!’ ? Si no es muy probable, simplemente elimine todo después del último ‘!’ en cada linea:

 def cleanup(line): splitlist = line.split("!") if len(splitlist) > 1 and "\"" not in splitlist[-1]: return '!'.join(splitlist[:-1]).strip() else: return line 

Esto no es perfecto, pero en el peor de los casos, terminarás dejando algunos comentarios parciales. Esto nunca debería afectar el código real.

Editar:

Parece que NumPy incluye un analizador Fortran basado en python en el paquete F2py . Dependiendo de las restricciones de la licencia, es posible que pueda volver a trabajar para analizar de manera confiable ‘código pero no comentarios’.

Lo que necesita es una afirmación negativa detrás de la afirmación: (? .

Por ejemplo:

 z = r'''print "h\"i!" ! Remove me''' pattern = r'''(?:[^!"]|(? 

Salida:

 print "h\"i!" 

Como se señaló en los comentarios, la expresión anterior no manejará barras invertidas escapadas. Tampoco manejará las comillas simples que están permitidas en FORTRAN. Este también debería funcionar para esos casos (creo):

  pattern = r'''(?:[^!"']|((? 

Esto se está poniendo un poco feo. . .