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...