Expressões Regulares - (?m)

7 respostas
E

Ola amigos, estou fazendo um pequeno programinha de teste de expressões regulares em Java, e estou tendo o seguinte problema:
Digamos que eu queria testar uma padrão da forma:

jorge1
jorge2
jorgeA
jorgeB
jorge

Se fosse para testar linha por linha bastaria usar: (uma linha de cada vez)

jorge.*

Pois bem, mais eu quero que isso seja procurado em múltiplas linhas. Ou seja.

(?m)^jorge.*

Contudo não está funcionado como as fotos abaixo mostram:

Quando uso:

(?m)^jorge.*

Ele só aceita a primeira linha… quando coloco outra linha ele rejeita…

Contudo quando uso:

(?ms)^jorge.*

Com o DOTTAL (?s) então ele aceitas, MAS ACEITA qualquer coisas inclusive algo que não inicia com jorge

Então eu gostaria de saber de vocês como usar o (?m) com expressões regulares em Java para trabalhar com múltiplas linhas?

7 Respostas

E

http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#MULTILINE - ele diz que o pacote de expressões regulares do Java aceita “(?m)”. Nunca tentei usar isso, no entanto :frowning:

E

Só uma pergunta - você não expressou corretamente seu problema.
Pelo que imagino, você tem um texto com várias linhas, e você quer que TODAS comecem com o nome daquele santo da novela, certo?

E
E

entanglement:
Só uma pergunta - você não expressou corretamente seu problema.
Pelo que imagino, você tem um texto com várias linhas, e você quer que TODAS comecem com o nome daquele santo da novela, certo?

Parceiro quando disse:

Você entendeu oque exatamente?

SIM É ISSO QUE EU QUERO… FOI O QUE EU PERGUNTEI:

Então eu gostaria de saber de vocês como usar o (?m) com expressões regulares em Java para trabalhar com múltiplas linhas?

(?m)^jorge.*

SIM EU LI A DEFINIÇÃO DA API DO JAVA…

Mas minha pergunta é: “Como o que você escreveu responde a pergunta???”
Eu não sou mais agradecido mas vc não respondeu nada, diz que eu não fiz a pergunta direito posta o texto da documentação Java API e não responde a pergunta…

O que exatamente você esperava com essa resposta?

Nota: jorge é o meu nome.

E

Claro que eu sei que Jorge é o nome de batismo daquele papa argentino :slight_smile: - então vamos ver como é que o tal padrão pode ser encontrado.
Infelizmente, o que você acha que funcionaria (^Jorge.)+ não funciona do jeito que você pensa, ele acaba sendo equivalente a ^Jorge.

Usei Pattern.MULTILINE em vez de (?m) porque é questão de estilo.
Eu simplesmente acho expressões regulares complicadas demais para que você não aproveite cada
chance de torná-las um pouco mais compreensíveis.

package guj;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMultilinePattern {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String teste = "Jorge Mario Bergoglio, papa\r\nJorge Mário da Silva, cantor\r\nJorge Leal Amado de Faria, escritor\r\nJorge Ney Viana Macedo Neves, senador\r\nGeorge Corbisier, engenheiro";
        // Note que o padrão (^Jorge.*)+ é interpretado pelo Java como se fosse equivalente a ^Jorge.*
        // Deve ser algo relativo à implementação das expressões regulares. 
        // O máximo que posso fazer é usar repetidamente o "find" para ir achando cada pedaço disponível :)
        Pattern pat = Pattern.compile ("^Jorge.*", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
        Matcher mat = pat.matcher(teste);
        while (mat.find()) {
            System.out.println ("[" + mat.group() + "]");
        }
    }
}

Note que o sr. George Corbisier, engenheiro, não aparece na saída, tal como você esperaria :slight_smile:

E

Parceiro obrigado pelas respostas, veja bem, minha dúvida é em relação ao uso do (?m), de forma que eu imaginava que a minha regex, da forma:

(?m)^jorge.*

Estaria errada para cruzar padrões que iniciassem com jorge em várias linhas, ok!
Eu quero usar o (?m) em Java.

Essa regex funciona em outros programa de teste de regex, como o : Rad Software Regular Expression Disigner.
Funciona em PHP
Funciona em C#

Como foto abaixo.
Como URL, para não bagunçar o texto.
https://sites.google.com/site/autotechsoftware/home/regex5.png

Minha pergunta é justamente por que não funciona no Java, alguém sabe?
Por que o uso do modificador (?m) não funciona da “forma esperada” no Java, encontrei muitos posts gringos falando sobre o uso de MULTILINE, mas eu realmente quero usar o (?m) por questões de estudo, meu foco é na regex (de forma que é a expressão que deveria informação se é mult ou single line!), fico pensando, será que que não foi implementado isso em Java, será que tem algum “bug”, segredo ou macete? Mas como pode? Está na documentação! É essa minha pergunta como usar o (?m) para pesquisar em multiplas linhas???
Alguém já teve problemas semelhante, especificamente com o uso do (?m), funciona perfeitamente em PHP e C#, funciona no programa de teste de regex mas em Java estranhamente o modificador (?m) não funciona… OU eu não estou sabendo como usa-lo, sendo assim, como se usa?

Grato.

Nota: NÃO TEM COMO EU ESPERAR QUE O NOME DO George Corbisier estivesse na lista, só os que iniciam com Jorge.

Para ficar mais claro ainda:

Por que este código não funciona? (Não imprime aceito)

package regexteste;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTeste {
    public static void main(String[] args) {
        String teste = "jorge1\njorge2\njorge3";
        Pattern pat = Pattern.compile ("(?m)^jorge.*");
        // ou Pattern pat = Pattern.compile ("^Jorge.*", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
        Matcher mat = pat.matcher(teste);

        if(mat.matches()) {
            System.out.println("Aceito");
        }
        else
            System.out.println("Errado!");
    }
}

Contudo se eu usar:

package regexteste;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTeste {
    public static void main(String[] args) {
        String teste = "jorge1\njorge2\njorge3";
        Pattern pat = Pattern.compile ("(?m)^jorge.*");
        // ou Pattern pat = Pattern.compile ("^Jorge.*", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
        Matcher mat = pat.matcher(teste);

        while(mat.find()) {
            System.out.println(mat.group());
        }
    }
}

Mas matches()

Não deveria emparelhara (cruzar) a região toda?

E

Agora está funcionando do jeito que eu queria. (Ou seja, os dois Jorges que não são Jorges mas sim Georgios e George foram removidos, assim como o outro Jorge cujo nome começa por Mário :slight_smile: )

Cuidado que neste caso depende muito de como é o retorno de linha presente nas strings, se houver “\r” na string você precisa eliminá-lo antes.

package guj;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMultilinePattern {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String teste = "Mário Jorge Lobo Zagalo, treinador\nGeorgios Papadoupoulos, ditador\nJorge Mario Bergoglio, papa\nJorge Mário da Silva, cantor\nJorge Leal Amado de Faria, escritor\nJorge Ney Viana Macedo Neves, senador\nGeorge Corbisier, engenheiro";
        Pattern pat = Pattern.compile ("(^Jorge.*\n)+", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
        Matcher mat = pat.matcher(teste);
        if (mat.find()) {
            System.out.println ("[" + mat.group() + "]");
        }
    }
}

Saída:

[Jorge Mario Bergoglio, papa
Jorge Mário da Silva, cantor
Jorge Leal Amado de Faria, escritor
Jorge Ney Viana Macedo Neves, senador
]
Criado 9 de abril de 2013
Ultima resposta 10 de abr. de 2013
Respostas 7
Participantes 2