2011-07-07 11 views
5

Por lo que puedo decir, MySQL no admite la recuperación del valor de un grupo de captura de una coincidencia de expresiones regulares. He encontrado extensiones del lado del servidor (lib_mysqludf_preg) que agregarían esta funcionalidad pero no podré instalar esta extensión en mi entorno.Simulación de grupos de captura de expresiones regulares en mysql

Por lo tanto, estoy buscando una manera de simular la captura de una parte de una coincidencia de expresiones regulares como una columna en una consulta SQL.

Mis datos se parece a la siguiente (y no puedo cambiar el formato de los datos en el servidor):

+-----------------------------+ 
| Version      | 
+-----------------------------+ 
| 1.2.3.4      | 
| 10.20.30.40     | 
| Obsidian-1.2.3.4   | 
| Obsidian-11.21.31.41  | 
| custom\Obsidian-11.21.31.41 | 
| custom\11.21.31.41   | 
+-----------------------------+ 

Busco para capturar cada uno de los 4 últimos dígitos de cada fila. Los dígitos son siempre la última parte del valor y siempre están separados por puntos. La siguiente expresión regular sería el fósforo todos los valores que desee:

.*[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+$ 

El resultado que estoy esperando es una combinación de funciones para capturar cada dígito como una columna de modo que pueda utilizar el dígito en la cláusula where de mi consulta, así como poder recuperar el número de versión.

SELECT 
    function1(...) as version1, 
    function2(...) as version2, 
    function3(...) as version3, 
    function4(...) as version4 
FROM Version 
WHERE version1 > 5; 
+0

¿Por qué no simplemente hacer esto en un lenguaje de programación de su elección? – Qtax

+1

Al menos puede obtener el último número fácilmente con 'SUBSTRING_INDEX (ver, '.', -1) como versión4'. Los otros son posibles de meterse con [funciones de cadena de MySQL] (http://dev.mysql.com/doc/refman/5.5/en/string-functions.html). No sé si hay una forma mejor sin instalar extensiones. – Qtax

Respuesta

3

Después de algo de ensayo y error que ocurrió la siguiente consulta que hace lo que necesito. Básicamente separa los números del final de la cadena y luego elimino esos muchos caracteres antes de separar el siguiente número. La columna version1 está limitada a números positivos de 2 dígitos, pero esa es una limitación con la que puedo vivir en mi caso.

SELECT 
    IF(CAST(RIGHT(SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -3)) - 1), '.', -1),2) AS DECIMAL) > 0, 
     CAST(RIGHT(SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -3)) - 1), '.', -1),2) AS DECIMAL), 
     CAST(RIGHT(SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -3)) - 1), '.', -1),1) AS DECIMAL)) AS version1, 
    SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -2)) - 1), '.', -1) as version2, 
    SUBSTRING_INDEX(LEFT(version,CHAR_LENGTH(version) - CHAR_LENGTH(SUBSTRING_INDEX(version, '.', -1)) - 1), '.', -1) as version3, 
    SUBSTRING_INDEX(version, '.', -1) as version4 
FROM Version 
HAVING version1 >= 5 
; 
Cuestiones relacionadas