Jump to content
ruimcosta

mysql regex

Recommended Posts

ruimcosta

Biba,

Num campo tenho valores com o formato 'xxx10299' ou 'xxyyy099'. Preciso de os transformar em 'xxx/10299' e 'xxyyy/099' ou seja, separar texto de números com uma barra. É sempre letras e depois numeros, nunca sabendo se tem no inicio 3,4,5,6 letras.

Como posso resolver isto, vocês tem alguma ideia?


Abraços e beijinhos,Rui Costa

Share this post


Link to post
Share on other sites
brunoais

Algo do tipo:

[A-z]{3,6}[0-9]+

?


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
ruimcosta

Lfscoutinho: Já andei por aí mas isso só me confirma se o valor está ou não no formato especificado.

Brunoais: O número de letras a esquerda e o número de números á direita não é sempre igual nem o tamanho da string é igual.

O que quero não é verificar se o formato corresponde, o que quero é "retirar" da string as letras, retirar os numeros e no final juntar os dois separados por uma /.

Obrigado pelas dicas, entretanto se surgirem ideias avisem pf., que eu tambem vou pesquisando. Consigo resolver com php, mas se puder passar a "bola" para o mysql, melhor.


Abraços e beijinhos,Rui Costa

Share this post


Link to post
Share on other sites
Rechousa

Olá,

Não me parece que vás conseguir apenas com REGEX (mas vai ajudar) e digo isto porque a funcção REGEX apenas retorna 1 (o texto está validado pela expressão regular) ou 0 (o texto não está validado pela expressão regular).

O que o ruimcosta pretende é separar a parte as letras dos algarismos e introduzir uma barra lá pelo meio.

Presumo que o ruimcosta queria executar este procedimento apenas uma vez. Se assim for, a questão de performance não é crítica (a meu ver). É uma coisa que se faz uma vez, fica feito e assunto resolvido.

Dados Adquiridos:

a) Existe apenas letras e números;

:) Os números começam a partir do caracter 4 (em que existem apenas 3 letras)

c) Os números, no máximo, começam a partir do caracter 7 (em que existem 6 letras)

Tinha pensado no seguite algorimo:

1) Vais verificar se existem algarismos (aqui o REGEX vai ser útil) nos primeiros 6 caracteres)

2) Vais garantir que o campo que pretendes actualizar não contém a barra ('/')

3) Desta forma vais conseguir obter a lista dos registos em que os primeiros seis caracteres são apenas letras e o restante são algarismos. Assim, vais conseguir actualizar o campo

4) Vais repetir o processo, mas em que consideras apenas 5 caracteres

Recomendo que antes de alterares o valor campo faças um SELECT para ver como vai ficar e, se ficar como pretendido, então aí sim, fazes os updates (um backup poderá ser útil)

SELECT campo AS 'Antigo', LEFT(campo, 6) + '/' + SUBSTRING(campo, 7) AS 'Novo' FROM tabela WHERE (LEFT(campo, 6) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'
SELECT campo AS 'Antigo', LEFT(campo, 5) + '/' + SUBSTRING(campo, 6) AS 'Novo' FROM tabela WHERE (LEFT(campo, 5) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'
SELECT campo AS 'Antigo', LEFT(campo, 4) + '/' + SUBSTRING(campo, 5) AS 'Novo' FROM tabela WHERE (LEFT(campo, 4) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'
SELECT campo AS 'Antigo', LEFT(campo, 3) + '/' + SUBSTRING(campo, 4) AS 'Novo' FROM tabela WHERE (LEFT(campo, 3) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'

Os Update's serão algo do género:

UPDATE tabela SET campo = LEFT(campo, 6) + '/' + SUBSTRING(campo, 7) FROM tabela WHERE (LEFT(campo, 6) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'
UPDATE tabela SET campo = LEFT(campo, 5) + '/' + SUBSTRING(campo, 6) FROM tabela WHERE (LEFT(campo, 5) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'
UPDATE tabela SET campo = LEFT(campo, 4) + '/' + SUBSTRING(campo, 5) FROM tabela WHERE (LEFT(campo, 4) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'
UPDATE tabela SET campo = LEFT(campo, 3) + '/' + SUBSTRING(campo, 4) FROM tabela WHERE (LEFT(campo, 3) REGEXP [0-9] = 0) AND NOT campo LIKE '%/%'

Espero ter ajudado

PS: Código não testado :D


Pedro Martins

Sharing is Knowledge!

http://www.linkedin.com/in/rechousa

Share this post


Link to post
Share on other sites
mAiN_iNfEcTiOn

Ora :D eu vou sugerir uma coisa feia.... :) Lamento... ou isso ou stored procedures ... portanto, se quiserem a stored procedure tb eh peanuts:

SELECT
REPLACE(campo,
    REPLACE(
        REPLACE(
            REPLACE(
                REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        REPLACE(campo,'1','')
                                    ,'2','')
                                ,'3','')
                            ,'4','')
                        ,'5','')
                    ,'6','')
                ,'7','')
            ,'8','')
        ,'9','')
    ,'0','')
,CONCAT(
    REPLACE(
        REPLACE(
            REPLACE(
                REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        REPLACE(campo,'1','')
                                    ,'2','')
                                ,'3','')
                            ,'4','')
                        ,'5','')
                    ,'6','')
                ,'7','')
            ,'8','')
        ,'9','')
    ,'0','')
  ,'/')
)

FROM tabela;

:) :) Pah, foi a solução mais ... enfim que arranjei

CORRIGIDO ... Tinha bug

Share this post


Link to post
Share on other sites
ruimcosta

Biba,

Obrigado a todos.

@mAiN_iNfEcTiOn: Resultou. Será mais "eficaz" transformar este código numa function ou SP? Se for via Sp, como ficaria?


Abraços e beijinhos,Rui Costa

Share this post


Link to post
Share on other sites
mAiN_iNfEcTiOn

Para retorno seria melhor a função... se for para efectuar o procedimento, seria via SP... Eis o exemplo de uma function:

DROP FUNCTION IF EXISTS a_tua_funcao;
DELIMITER //
CREATE FUNCTION a_tua_funcao(texto VARCHAR(255))
RETURNS VARCHAR(255)
BEGIN
DECLARE pos INT DEFAULT 1;
DECLARE ascii_value INT DEFAULT NULL;
set ascii_value = ASCII(SUBSTRING(texto,pos,1));
WHILE (pos<LENGTH(texto)) AND (ascii_value NOT BETWEEN 48 AND 57) DO
	SET pos = pos+1;
	SET ascii_value = ASCII(SUBSTRING(texto,pos,1));
END WHILE;
RETURN CONCAT(SUBSTRING(texto,1,pos-1),'/',SUBSTRING(texto,pos));
END
//
DELIMITER ;

SELECT a_tua_funcao('afsafasf1234'); # Retorno afsafasf/1234

Claro está que a função está muito simples e limitada a códigos até 255 caracteres. ;) mas é só editares :)

Share this post


Link to post
Share on other sites
ruimcosta

Obrigado,

Resultou na perfeição.


Abraços e beijinhos,Rui Costa

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.