Como pegar dados dentro de uma String

13 respostas
C

Boa Noite Pessoal,

Gostaria da ajuda de vocês em um problema que talvez seja fácil. Eu pesquisei sobre split, StringTokenizer e Regex. Mas utilizei eles e não funcionou como eu queria ou provavelmente não consegui a lógica necessária para resolver meu problema.
Então minha dúvida é a seguinte, preciso capturar os dados que vem de uma porta serial, esses dados estão armazenados em uma string. O problema é que vem muito lixo junto e eu precisaria apenas do número do telefone e da mensagem que está no texto, sendo que, possui varias mensagens de vários números diferentes nesse texto.
Segue exemplo da captura da porta serial:

+CSQ: 27,99
OK
OK
+CMGL: 0,"REC READ","+[telefone removido]",,"15/03/24,15:29:23-12"
Mensagem01
+CMGL: 1,"REC READ","+[telefone removido]",,"15/03/24,15:38:58-12"
Mensagem02
+CMGL: 2,"REC READ","+554981587952",,"15/03/24,15:41:37-12"
Mensagem03
+CMGL: 3,"REC READ","+552584587",,"15/03/24,15:41:45-12"
Mensagem04

Pelo que percebi o melhor é utilizar o Regex, só que não consegui formular a lógica necessária para ter apenas o número do celular e a mensagem. Se alguém puder me ajudar agradeço muito. Desde já agradeço atenção de todos.

OBS: Estou utilizando comandos AT.

13 Respostas

viniciusalvess

você recebe um array de bytes do stream da serial e transforma-o em string ? como chega os dados pra você ? coloca aí uma parte do código.

C

Sim exatamente como vc falou que eu faço, os dados chega igual do exemplo que passei aí em cima.

Segue código de leitura da porta serial:

public void serialEvent(SerialPortEvent ev) {
        StringBuilder bufferLeitura = new StringBuilder();
        int novoDado = 0;

        switch (ev.getEventType()) {
            case SerialPortEvent.BI:
            case SerialPortEvent.OE:
            case SerialPortEvent.FE:
            case SerialPortEvent.PE:
            case SerialPortEvent.CD:
            case SerialPortEvent.CTS:
            case SerialPortEvent.DSR:
            case SerialPortEvent.RI:
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                break;
            case SerialPortEvent.DATA_AVAILABLE:
                //Algortimo de leitura
                while (novoDado != -1) {
                    try {
                        novoDado = entrada.read();
                        if (novoDado == -1) {
                            break;
                        }
                        if ('\r' == (char) novoDado) {
                            bufferLeitura.append('\n');
                        } else {
                            bufferLeitura.append((char) novoDado);
                        }
                    } catch (IOException ioe) {
                        System.out.println("Erro de leitura serial: " + ioe);
                    }
                }
                setDado(new String(bufferLeitura));
               recebeuDado();
                break;
        }
    }

    //Método para conferir se recebeu dados

    public void recebeuDado() {
        List lista = new ArrayList<>();
        String dado = getDado();
     //aqui sao apenas testes que tentei quebrar o testo 
        StringTokenizer st = new StringTokenizer(dado, "\n");
//tentar armazenar só o que eu quero em um vetor
        String [] linhas = dado.split("REC READ");
        while(st.hasMoreTokens()){
            System.out.println(st.nextToken());
        }
    }
jweibe

public static void main(String[] args) { String str = "+CSQ: 27,99" + "OK" + "OK" + "+CMGL: 0,\"REC READ\",\"+[telefone removido]\",,\"15/03/24,15:29:23-12\"" + "Mensagem01" + "+CMGL: 1,\"REC READ\",\"+[telefone removido]\",,\"15/03/24,15:38:58-12\"" + "Mensagem02" + "+CMGL: 2,\"REC READ\",\"+554981587952\",,\"15/03/24,15:41:37-12\"" + "Mensagem03" + "+CMGL: 3,\"REC READ\",\"+552584587\",,\"15/03/24,15:41:45-12\"" + "Mensagem04 "; Pattern pattern = Pattern.compile("\"(\\+)[0-9]{9,}\""); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println("Telefone: "+matcher.group()); } }
saída:

Telefone: "+[telefone removido]"
Telefone: "+[telefone removido]"
Telefone: "+554981587952"
Telefone: "+552584587"
C

Funcionou Muito Obrigado jweibe . Só que dai para pegar a mensagem, que essa mensagem vai ter números também nela, eu posso usar também o Regex ou devo usar outra função?

jweibe

se o padrão for o mesmo… pode usar sim, senão você adapta.

C

Só mais uma dúvida dai marco o tópico resolvido, se eu quiser juntar essa expressão (.# ([0-9\-]+).) como poderia fazer para que o resultado ficasse assim:

"Telefone = " +[telefone removido] "Mensagem" = 12587

Eu queria juntar duas expressões sendo que dai na hora de mostrar eu colocava como matcher.group(1) e matcher.group(2). Eu tentei dessa maneira mas não mostra:

// o # caracter de controle para pegar a mensagem 
         Pattern pattern = Pattern.compile("\"(\\+)[0-9]{9,}\" , .*# ([0-9\\-]+).*");  
        Matcher matcher = pattern.matcher(dado);  
        while (matcher.find()) {  
            System.out.println("Telefone: "+matcher.group(1) + "Mensagem: "+matcher.group(2));  
        }

Obrigado pela ajuda até o momento

Rodrigo_Sasaki

Bom, nesse caso você precisa descobrir qual é o padrão que define onde começa e termina a mensagem, por exemplo:

No número de telefone sabemos que ele começa com um + seguido de dígitos, no caso a única coisa que conseguimos definir, de acordo com seu exemplo, é que ele tem no mínimo 9 dígitos. Então podemos ter um Pattern assim:Pattern pattern = Pattern.compile("\\+\\d{9,}"); Se você não quer limitar o número de digitos pode usar um outro quantificador também: Pattern pattern = Pattern.compile("\\+\\d+"); Você precisa descobrir qual é o padrão que define a mensagem, caso exista, e aí pode montar uma expressão regular para ele.

C

Acho que não me expressei de forma clara. Assim eu tenho já a expressão regular para pegar a MENSAGEM (que funciona como preciso, pois testei) que seria essa:

// expressao regular para pegar a mensagem 
// # -> caracter de controle para pegar a mensagem
Pattern pattern = Pattern.compile(".*# ([0-9\\-]+).*");

Mas ela só me mostra a mensagem, mas eu queria pegar o telefone também junto com a mensagem, que a do telefone seria essa:

// expressao regular para pegar o TELEFONE
 Pattern pattern = Pattern.compile("\"(\\+)[0-9]{9,}\"");

Então eu queria conseguir usar as duas expressões regulares, em um só PATTERN, para eu saber de qual telefone que é uma determinada mensagem. Desta foma:

System.out.println("Telefone: "+matcher.group(1) + "Mensagem: "+matcher.group(2));

Não sei se consegui deixar claro meu problema. Mas mesmo assim obrigado pela ajuda =)

pmlm

E usando dois patterns e dois matchers?

System.out.println("Telefone: "+matcherT.group(1) + "Mensagem: "+matcherM.group(1));
Rodrigo_Sasaki

Você pode até fazer com um único pattern e 2 grupos, mas aí tem que tratar exatamente o que pode vir entre as 2 informações. Aí cabe a você decidir se sua situação é simples o suficiente pra isso, ou se é melhor mostrar patterns separados.

Você tem algum exemplo de dado? Aquele exemplo seu acima é um valor real?

C

Sim um Exemplo seria esse mesmo:

+CSQ: 27,99  
OK  
OK  
+CMGL: 0,"REC READ","+[telefone removido]",,"15/03/24,15:29:23-12"  
#Mensagem01  
+CMGL: 1,"REC READ","+[telefone removido]",,"15/03/24,15:38:58-12"  
#Mensagem02  
+CMGL: 2,"REC READ","+554981587952",,"15/03/24,15:41:37-12"  
#Mensagem03  
+CMGL: 3,"REC READ","+552584587",,"15/03/24,15:41:45-12"  
#Mensagem04

O problema de eu fazer dois patterns e dois matchers é que pode ser que certo momento a mensagem venha diferente, tipo sem o # que seria o carácter de controle. E assim não dando certo para gravar no banco de dados os valores certos :SS

Rodrigo_Sasaki
Bom, usando esse seu exemplo você pode fazer o seguinte:
public class Teste {

    public static void main(String[] args) {
        String str = "+CSQ: 27,99" +
                     "OK" +
                     "OK" +
                     "+CMGL: 0,\"REC READ\",\"+[telefone removido]\",,\"15/03/24,15:29:23-12\"" +
                     "#Mensagem01" +
                     "+CMGL: 1,\"REC READ\",\"+[telefone removido]\",,\"15/03/24,15:38:58-12\"" +
                     "#Mensagem02" +
                     "+CMGL: 2,\"REC READ\",\"+554981587952\",,\"15/03/24,15:41:37-12\"" +
                     "#Mensagem03" +
                     "+CMGL: 3,\"REC READ\",\"+552584587\",,\"15/03/24,15:41:45-12\"" +
                     "#Mensagem04";

        Pattern pattern = Pattern.compile("(\\+\\d{9,}).*?(#.+?\\b)");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println("Telefone: " + matcher.group(1));
            System.out.println("Mensagem: " + matcher.group(2));
            System.out.println();
        }
    }

}
Onde o primeiro grupo é definido por uma expressão que espera um caractere + seguido de no mínimo 9 caracteres numéricos, você pode ter que alterar isso para tratar hífens como fez em exemplos acima.

E a segunda expressão espera um caractere # seguido de qualquer coisa até o fim de um boundary, o que pode não ser bom o suficiente pra você, caso existam espaços na mensagem, mas isso também pode ser tratado de alguma forma.

E mais um detalhe, se seu exemplo tem quebras de linha (na forma que montei o texto todo está em uma única linha) é só você adicionar a opção Pattern.DOTALL ou (?s), para que o interpretador aceite quebras de linha quando você estiver usando o ponto (.).

Basta fazer assim:
Pattern pattern = Pattern.compile("(\\+\\d{9,}).*?(#.+?\\b)", Pattern.DOTALL);
C

Muito obrigado a todos, consegui resolver meu problema com a ajuda de vcs :DD

RESOLVIDO

Criado 31 de março de 2015
Ultima resposta 20 de abr. de 2015
Respostas 13
Participantes 5