Ajuda com expressão regular

6 respostas
kemperacc

Srs,

Estou precisando fazer uma expressão regular que case o padrão abaixo:

14754310000030742-8               00/00/0000  15/03/2010     138,88    1,80     0,00        0,00  LQR    137,08 *                  372

Explicando,

Campo 1: Número do documento, pode ter de 1 a 30 digitos seguido de um hifem e um digito verificador
Campo 2: Vencimento, (vem sempre 00/00/0000 mas pode vir a data também)
Campo 3: Data Pagamento (vem sempre no formato DD/MM/AAAA)
Campo 4: Valor do documento, vem o valor alinhado a direita (com 9 digitos 99999,99)
Campo 5: Tarifa, vem o valor alinhado a direita (com 7 digitos 9999,99)
Campo 6: Acrescimo, vem o valor alinhado a direita com 8 digitos
Campo 6: Desconto, vem o valor alinhado a direita com 9 digitos
Campo 7: LQR (sempre vem isso escrito ou outra sigla, que pra mim é indiferente)
Campo 8: Valor recebido vem alinhado a direita com 9 digitos
Campo 9: * (sempre vem um *)
Campo 10: Local de recebimento, sempre vem um numero de ate 5 digitos

Inicialmente fiz a seguinte expressao:

String regExp = "^[0-9]{1,30}-[0-9]"

Porem nao funcionou, ai fiz o seguinte codigo para testar:

Pattern regExp = Pattern.compile("^1*");
        String linha = "14754310000030395-3               00/00/0000  15/03/2010     155,00    1,80     0,00        0,00  LQR    153,20 *                 3329";

        Matcher pesquisa = regExp.matcher(linha);

        if (pesquisa.matches()) {
            System.out.println("OK");
        }else{
            System.out.println("FALSO");
        }

Alguem saberia me indicar onde esta o erro? Neste exemplo que passei, imprime FALSO sempre, e pelo que eu entendo a expressao: ^1* seria que começe com 1 seguido de qualquer coisa

Mesmo assim nao esta funcionando!

Alguem poderia me dar um help (deixei meu livro do aurelio la em casa! hehehe)

Obrigado.

6 Respostas

Ataxexe

Na verdade o 1* significa encontrar o caractere 1 zero ou mais vezes.

Quebrando um pouco o seu galho, a expressão regular de mais simples entendimento seria:

^(\d{1,30}-\d)\s*(\d{2}/\d{2}/\d{4})\s*(\d{2}/\d{2}/\d{4})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\w+)\s*(\d+,\d{2})\s*\*\s*(\d{1,5})$

Cada campo que você se referiu no post pode ser usado com “$” (o campo 1 seria $1 e assim por diante). Apenas passe essa expressão regular para Java e pode usá-la sem medo.

No exemplo que você deu, eu gerei a seguinte saída:

Campo1: 14754310000030395-3
Campo2: 00/00/0000
Campo3: 15/03/2010
Campo4: 155,00
Campo5: 1,80
Campo6: 0,00
Campo7: 0,00
Campo8: LQR
Campo9: 153,20
Campo10: 3329

Dá pra dar uma melhorada boa nessa expressão, aí fica com você!

kemperacc

Ataxexe:
Na verdade o 1* significa encontrar o caractere 1 zero ou mais vezes.

Quebrando um pouco o seu galho, a expressão regular de mais simples entendimento seria:

^(\d{1,30}-\d)\s*(\d{2}/\d{2}/\d{4})\s*(\d{2}/\d{2}/\d{4})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\w+)\s*(\d+,\d{2})\s*\*\s*(\d{1,5})$

Cada campo que você se referiu no post pode ser usado com “$” (o campo 1 seria $1 e assim por diante). Apenas passe essa expressão regular para Java e pode usá-la sem medo.

No exemplo que você deu, eu gerei a seguinte saída:

Campo1: 14754310000030395-3
Campo2: 00/00/0000
Campo3: 15/03/2010
Campo4: 155,00
Campo5: 1,80
Campo6: 0,00
Campo7: 0,00
Campo8: LQR
Campo9: 153,20
Campo10: 3329

Dá pra dar uma melhorada boa nessa expressão, aí fica com você!

Oi, obrigado, seu exemplo me ajudou, a expressao ficou assim:

Pattern regExp = Pattern.compile("[0-9]{1,30}-[0-9] {0,31}[0-9]{2}/[0-9]{2}/[0-9]{4} {2}[0-9]{2}/[0-9]{2}/[0-9]{4} {0,5}[0-9]{0,7},[0-9]{2} {0,4}[0-9]{0,4},[0-9]{2} {0,5}[0-9]{0,4},[0-9]{2} {0,8}[0-9]{0,9},[0-9]{2}  [A-Z]{3} {0,7}[0-9]{0,6},[0-9]{2} [*] {0,17}[0-9]{0,17} ");
        String linha = "14754310000030395-3               00/00/0000  15/03/2010     155,00    1,80     0,00        0,00  LQR    153,20 *                 3329 ";

        if (Pattern.matches(regExp.pattern(), linha)) {
            System.out.println("OK");
        }else{
            System.out.println("FALSO");
        }
Mikhas
kemperacc:
Ataxexe:
Na verdade o 1* significa encontrar o caractere 1 zero ou mais vezes.

Quebrando um pouco o seu galho, a expressão regular de mais simples entendimento seria:

^(\d{1,30}-\d)\s*(\d{2}/\d{2}/\d{4})\s*(\d{2}/\d{2}/\d{4})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\w+)\s*(\d+,\d{2})\s*\*\s*(\d{1,5})$

Cada campo que você se referiu no post pode ser usado com "$" (o campo 1 seria $1 e assim por diante). Apenas passe essa expressão regular para Java e pode usá-la sem medo.

No exemplo que você deu, eu gerei a seguinte saída:

Campo1: 14754310000030395-3 Campo2: 00/00/0000 Campo3: 15/03/2010 Campo4: 155,00 Campo5: 1,80 Campo6: 0,00 Campo7: 0,00 Campo8: LQR Campo9: 153,20 Campo10: 3329

Dá pra dar uma melhorada boa nessa expressão, aí fica com você!

Oi, obrigado, seu exemplo me ajudou, a expressao ficou assim:

Pattern regExp = Pattern.compile("[0-9]{1,30}-[0-9] {0,31}[0-9]{2}/[0-9]{2}/[0-9]{4} {2}[0-9]{2}/[0-9]{2}/[0-9]{4} {0,5}[0-9]{0,7},[0-9]{2} {0,4}[0-9]{0,4},[0-9]{2} {0,5}[0-9]{0,4},[0-9]{2} {0,8}[0-9]{0,9},[0-9]{2}  [A-Z]{3} {0,7}[0-9]{0,6},[0-9]{2} [*] {0,17}[0-9]{0,17} ");
        String linha = "14754310000030395-3               00/00/0000  15/03/2010     155,00    1,80     0,00        0,00  LQR    153,20 *                 3329 ";

        if (Pattern.matches(regExp.pattern(), linha)) {
            System.out.println("OK");
        }else{
            System.out.println("FALSO");
        }

Você pode usar "\d" no lugar de "[0-9]". Tem o mesmo efeito.

kemperacc
Mikhas:
kemperacc:
Ataxexe:
Na verdade o 1* significa encontrar o caractere 1 zero ou mais vezes.

Quebrando um pouco o seu galho, a expressão regular de mais simples entendimento seria:

^(\d{1,30}-\d)\s*(\d{2}/\d{2}/\d{4})\s*(\d{2}/\d{2}/\d{4})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\d+,\d{2})\s*(\w+)\s*(\d+,\d{2})\s*\*\s*(\d{1,5})$

Cada campo que você se referiu no post pode ser usado com "$" (o campo 1 seria $1 e assim por diante). Apenas passe essa expressão regular para Java e pode usá-la sem medo.

No exemplo que você deu, eu gerei a seguinte saída:

Campo1: 14754310000030395-3 Campo2: 00/00/0000 Campo3: 15/03/2010 Campo4: 155,00 Campo5: 1,80 Campo6: 0,00 Campo7: 0,00 Campo8: LQR Campo9: 153,20 Campo10: 3329

Dá pra dar uma melhorada boa nessa expressão, aí fica com você!

Oi, obrigado, seu exemplo me ajudou, a expressao ficou assim:

Pattern regExp = Pattern.compile("[0-9]{1,30}-[0-9] {0,31}[0-9]{2}/[0-9]{2}/[0-9]{4} {2}[0-9]{2}/[0-9]{2}/[0-9]{4} {0,5}[0-9]{0,7},[0-9]{2} {0,4}[0-9]{0,4},[0-9]{2} {0,5}[0-9]{0,4},[0-9]{2} {0,8}[0-9]{0,9},[0-9]{2}  [A-Z]{3} {0,7}[0-9]{0,6},[0-9]{2} [*] {0,17}[0-9]{0,17} ");
        String linha = "14754310000030395-3               00/00/0000  15/03/2010     155,00    1,80     0,00        0,00  LQR    153,20 *                 3329 ";

        if (Pattern.matches(regExp.pattern(), linha)) {
            System.out.println("OK");
        }else{
            System.out.println("FALSO");
        }

Você pode usar "\d" no lugar de "[0-9]". Tem o mesmo efeito.

Eu sei, mas pra colocar isso dentro de uma variavel ia ficar muito feio, pois ia ter que escapar todas as \ ia ficar muito \\s\\d muito estranho, preferi colocar assim pois ai fica mais "visual" quando tiver que dar manutencao nesse monstrinho...

Aproposito, havia um pequeno erro que corrigi, a regexp ficou assim (agora funcionando perfeito):

String regExp = "[0-9]{1,30}-[0-9] {0,31}[0-9]{2}/[0-9]{2}/[0-9]{4} {2}[0-9]{2}/[0-9]{2}/[0-9]{4} {0,7}[0-9]{0,7},[0-9]{2} {0,4}[0-9]{0,4},[0-9]{2} {0,5}[0-9]{0,4},[0-9]{2} {0,8}[0-9]{0,9},[0-9]{2}  [A-Z]{3} {0,7}[0-9]{0,6},[0-9]{2} [*] {0,21}[0-9]{0,21} {0,2}";
peczenyj

Ola

Sou suspeito para falar mas… validar todos estes campos com uma expressão regular pode te trazer dores de cabeça no futuro. Seria interessante vc criar as verificações identificadas para cada tipo de campo e junta-las em algum momento.

Por exemplo, se o seu schema mudar e vc tiver algum campo numero com um caracter a mais (ou a menos) vc vai ter que ficar contando 1, 2, 3… achei a expressão correta.

Algo como

String patternAll = pattern_numero_documento + pattern_data + … pattern10;

(Porem concatenado de uma forma inteligente, aqui é só para ilustrar)

Sem falar que seria bom analisar as datas (e ver o caso do 00/00/0000) e o digito verificador tb :wink:

kemperacc

peczenyj:
Ola

Sou suspeito para falar mas… validar todos estes campos com uma expressão regular pode te trazer dores de cabeça no futuro. Seria interessante vc criar as verificações identificadas para cada tipo de campo e junta-las em algum momento.

Por exemplo, se o seu schema mudar e vc tiver algum campo numero com um caracter a mais (ou a menos) vc vai ter que ficar contando 1, 2, 3… achei a expressão correta.

Algo como

String patternAll = pattern_numero_documento + pattern_data + … pattern10;

(Porem concatenado de uma forma inteligente, aqui é só para ilustrar)

Sem falar que seria bom analisar as datas (e ver o caso do 00/00/0000) e o digito verificador tb ;-)

Na verdade a informacao em si nao é importante para mim (no momento) apenas tenho que separar as linhas que possuem o padrao das que nao possuem, pois este arquivo vem com LIXO no inicio e no fim.

De qualquer forma, obrigado.

Criado 29 de março de 2010
Ultima resposta 30 de mar. de 2010
Respostas 6
Participantes 4