6 votos

¿Cuál es la expresión regular correcta para InChI?

Cuando busco una expresión regular para InChI, tengo éxito en Sitio web del Registro MIRIAM de la EBI :

^InChI\=1S?\/[A-Za-z0-9]+(\+[0-9]+)?(\/[cnpqbtmsih][A-Za-z0-9\-\+\(\)\,\/]+)*$

Y, efectivamente, funciona para algunos ejemplos (utilizando la herramienta de Python re módulo):

import re

pattern = '^InChI\=1S?\/[A-Za-z0-9]+(\+[0-9]+)?(\/[cnpqbtmsih][A-Za-z0-9\-\+\(\)\,\/]+)*$'

s = 'InChI=1S/C2H6O/c1-2-3/h3H,2H2,1H3'

re.findall(pattern, s)  

imprimirá

[('', '/c1-2-3/h3H,2H2,1H3')]

Sin embargo, si tomo otros ejemplos, como por ejemplo este

s2 = 'InChI=1S/C6H12O6/c7-1-2-3(8)4(9)5(10)6(11)12-2/h2-11H,1H2/t2-,3-,4+,5+,6?/m1/s1'

falla

re.findall(pattern, s2)

devolverá

[]

¿Cuál es la expresión regular correcta y general para InChI?

EDITAR

Si lo veo bien, en el patrón de arriba no se tienen en cuenta los signos de interrogación que se utilizan para marcar los centros quirales "desconocidos" e "indefinidos" . Si se ajusta la regex en consecuencia, al menos funciona para el ejemplo anterior; por supuesto, no está claro si es válido para todos los InChI.

pattern = '^InChI\=1S?\/[A-Za-z0-9]+(\+[0-9]+)?(\/[cnpqbtmsih][A-Za-z0-9\-\+\(\)\,\/\?]+)*$'

s2 = 'InChI=1S/C6H12O6/c7-1-2-3(8)4(9)5(10)6(11)12-2/h2-11H,1H2/t2-,3-,4+,5+,6?/m1/s1'

re.findall(pattern, s2)

devolverá

[('', '/c7-1-2-3(8)4(9)5(10)6(11)12-2/h2-11H,1H2/t2-,3-,4+,5+,6?/m1/s1')]

2voto

maccullt Puntos 1555

Mientras no esté buscando algo muy específico, y no esté realizando una comprobación de cordura de lo que está comparando, la expresión regular proporcionada coincidirá más veces de forma errónea que de forma falsa. Incluso coincidirá con más InChI sin sentido que el número total de los existentes. Por lo tanto, no es mucho mejor que la trivial captura de todos:

^InChI\=1S?\/[^\s]+(\s|$)

El espacio (y algunos otros) es un carácter que no formará parte de un InChI correcto. Por lo tanto, lo anterior coincidirá con todas las cadenas InChI correctas (y con muchas más), y sin duda con más correctas que la dada en la pregunta (o en su respuesta).

El principal problema de todo el planteamiento se da básicamente en el preguntas técnicas frecuentes en la sección 5 . Dependiendo de lo que estemos viendo, no todas las capas estarán presentes. Ni siquiera hay garantía de que esté presente una fórmula de suma, como la representada por el protón: InChI=1S/p+1 . Este (y sus parientes) es básicamente responsable de por qué el regex está condenado desde el principio, y de que no haya un regex correcto en primer lugar.

Si quisiéramos implementar sólo una pequeña fracción de control de sanidad para reducir el número de desajustes, pronto veremos que toda la cadena se convierte en una página. Examinemos la regex dada un poco más para entender realmente qué es y por qué su intento es inútil.

^InChI\=1S?\/[A-Za-z0-9\.]+(\+[0-9]+)?(\/[cnpqbtmsih][A-Za-z0-9\-\+\(\)\,\/\?\;\.]+)*$

A partir de

^  

coincide con el inicio de la cadena, lo que no es realmente necesario

 InChI\=1S?

coincide con el prefijo, mientras que lo deja abierto si es estándar o no

           \/[A-Za-z0-9\.]+(\+[0-9]+)?

coincide con una fórmula de suma (incluso las tontas) o cualquier cosa que no tenga una capa principal y vaya directamente a los isótopos o a las cargas, etc. Lo mejor sería aquí hacer que la fórmula de la suma fuera opcional, es decir (\/[A-Za-z0-9\.]+)?

                                      (\/[cnpqbtmsih][A-Za-z0-9\-\+\(\)\,\/\?\;\.]+)*$

esto es una forma elegante de decir que se puede hacer coincidir cualquier tipo de capa, tantas veces como se quiera,( o no,) en el orden que sea conveniente, con cualquier contenido. Sin embargo, no coincide con * que es lo que debe hacer: InChI=1S/2C2H5.Zn/c2*1-2;/h2*1H2,2H3; como se indica en las FAQ.

Un enfoque mucho mejor sería emparejar las capas por separado, para tener un poco de control, ya que tienen un orden predefinido. Por ejemplo, empezar con la capa de conectividad 1.1 (\/c[0-9\-\*\;\(\)]+)? , pasar a la capa de conectividad 1.2 o de hidrógeno (\/h[H0-9,\(\)\;]+)? . No estoy muy seguro de haber captado todos los caracteres especiales que podrían insertarse. A continuación, coincidir con la carga (\/q(\+|\-)+[1-9]+[0-9]*)? y el balance de protones \/p , las distintas capas estereoquímicas, las capas fijas, etc. Hay muchas. Probablemente tengo la carga ya medio mal, ya que no estoy seguro de si necesita ; o no.

Conseguir una regex correcta y no demasiado codiciosa para cada capa ya es una buena tarea, y si puedes hacer algo útil con ella, bien. Para todo lo demás, hay una razón por la que existe un software para crear y analizar esas cadenas. Para cualquier otro propósito, el codicioso match-it-all del principio debería funcionar perfectamente. Ahora bien, las InChIKeys son algo muy diferente...

1voto

Puede que esta no sea la versión final, pero cubre todos los casos que he encontrado hasta ahora (si encuentras un InChI que no se puede emparejar con esta expresión, por favor, publícalo en los comentarios junto con una fuente, para que se pueda adaptar la regex):

pattern = '^InChI\=1S?\/[A-Za-z0-9\.]+(\+[0-9]+)?(\/[cnpqbtmsih][A-Za-z0-9\-\+\(\)\,\/\?\;\.]+)*$'

Se han realizado los siguientes cambios en comparación con el publicado en la pregunta:

  1. También se tiene en cuenta . en la fórmula química; compruebe inchi-trust para un ejemplo
  2. Una toma ? en cuenta; compruebe inchi-trust para una explicación detallada
  3. También se comprueba que ; ; comprobar inchi-trust para un ejemplo
  4. También hay que tener en cuenta . en cuenta más adelante, no sólo en la fórmula química. Esto se explica en "El identificador químico internacional de la IUPIC" :

    /m paridad invertida para obtener el estéreo relativo ( 1 = invertido, 0 = no invertido, . = la inversión no afecta a la paridad)

Supongo que este post se actualizará en el futuro, pero para mis ejemplos ahora funciona y todos los cambios pueden ser respaldados por fuentes confiables.

La expresión regular es actualizado ahora a la que yo propuse. Aparentemente, están contentos de cambiar su expresión, así que si encuentras casos en los que una InChI no puede ser mapeado, por favor repórtelo a ellos o agréguelo aquí en los comentarios. Evidentemente, esta expresión regular también podría coincidir con cadenas que en realidad no son químicas, pero al menos uno debería ser capaz de identificar cada una de las cadenas válidas InChI como InChI .

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X