REGEX - negar String

Galera, to com um problemão:

Preciso reconhecer tudo o que existe dentro de uma tag, no caso:

<UML:Class(?si)(.*?)</UML:Class>

Isso não é problema, funciona legal, o problema é que existe uma tag, vou chamá-la de falsa
que não termina com </UML:Class> e não deve ser capturada …

<UML:Class xmi.id = '127-0-1-1-76664874:1185760bbbc:-8000:0000000000000816' name = 'String' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false' isActive = 'false'/>

O problema é que já tentei de tudo para capturar apenas a primeira tag, no caso a verdadeira, mas ele sempre pega as duas…

Me deparei com a seguinte situação: Ele captura tudo isso ae…
A falsa está dentro de uma tag que a verdadeira não esta, no caso a tag UML:Namespace.ownedElement

<UML:Namespace.ownedElement>
        <tagfalsa/>
</UML:Namespace.ownedElement>
<tagverdadeira>

</tagverdadeira>

Entretanto, ele captura tudo entre a e a

A minha regex para esse problema foi a seguinte, o eu tento negar a expressão namespace atraves do (?!):

<UML[:]Class xmi.id = (?!<UML[:]Namespace[.]ownedElement(?:.*?)/>)(?si)(.*?)</UML[:]Class>

Alguém pode me ajudar?

Aqui está o XML para teste:

<UML:Package xmi.id = '127-0-1-1--52a32396:1186228c68b:-8000:0000000000000822'
              name = 'util' isSpecification = 'false' isRoot = 'false' isLeaf = 'false'
              isAbstract = 'false'>
              <UML:Namespace.ownedElement>
                <UML:Interface xmi.id = '127-0-1-1--52a32396:1186228c68b:-8000:0000000000000823'
                  name = 'List' />
               <UML:Class 
                      ...
                  name = 'Time' />
              </UML:Namespace.ownedElement>
            </UML:Package>
          </UML:Namespace.ownedElement>
        </UML:Package>
         
         <UML:Class 
                ...
          name = 'classe3' isActive = 'false'>
                CONTEUDO QUE QUERO PEGAR
        </UML:Class>

A primeira tag class é a tag falsa e a segunda é a verdadeira

P.s: Não posso fazer parser com o DOM

Vou dar um exemplo com sed

$ sed -n '/<UML:Namespace.owned/,/<\/UML:Namespace.owned/d /<UML:Class/,/<\/UML:Cass/p' arquivo.xml <UML:Class ... name = 'classe3' isActive = 'false'> CONTEUDO QUE QUERO PEGAR </UML:Class>

Ok, vc vai dizer “q diabos é isso”.

Bom, a expressão regular que vc está procurando é demasiada complexa.

O que eu fiz:
-Removi do arquivo os trechos que tem o código indesejado (com o comando d do sed)
-Depois eu procurei a tag esperada (e imprimi com o comando p do sed)

Tenho certeza que o Perl suporta um tipo de expressão que nega uma string inteira (o padrão é negar um conjunto de caracteres [^lista] ou inverter a lógica do match se vc esta fazendo uma busca).

Minha sugestão: remova as tags indesejadas e depois procure o que vc deseja :slight_smile:

Olá peczenyj,

primeiramente, obrigado pela sua ajuda, entretanto, eu não tenho essa liberdade toda(remover o que é desnecessário) acerca o XML,
pq trata-se de um plugin do eclipse que está sendo extendido, e devido ao fato de eu criar a expressão que o plugin irá reconhecer, não posso excluir nada, ou usar replaceAll por exemplo, nem tampouco usar mais de uma expressão, ou usar o linux com o sed…

é preciso uma expressão só que pegue tudo de uma só vez… e realmente… é demasiada complexa…
Mas obrigado mesmo assim…

Alguém conseguiria construir essa expressão?
Obrigado a todos

Em Perl e Java você usaria “(?!”. Para mais detalhes, veja o site do sr. Aurélio:

http://www.aurelio.net/er/

Sim sim… foi de la que eu vi isso (?! e utilizei na expressão que está no primeiro topico desse forum…
mas num consegui fazer funcionar… =(

Desculpe, mas eu falei "(?!", não "(?si", que faz o seguinte: s = "DOTALL" (ou seja, as quebras de linhas são capturadas por ".", e i = "CASE_INSENSITIVE". )

Vou dar um exemplo do uso de "(?!" (que tem um nome esotérico na documentação do Java - "(?!X) X, via zero-width negative lookahead".

Rode o exemplo abaixo.

import java.util.regex.*;
import java.util.*;

class TesteExceto {
    public static void main(String[] args) {
        String regexValida = &quot;&lt;\\d{8}&lt;\\d{10}&gt;\\d{12}:&quot;;
        String regexInvalida = &quot;&lt;[0]{8}&lt;[0]{10}&gt;[0]{12}:&quot;;        
        String[] test = {
            &quot;&lt;12345678&lt;1234567890&gt;123456789012:&quot;,
            &quot;&lt;00000000&lt;0000000000&gt;000000000000:&quot;,
            &quot;0000000000000000000000000000000000&quot;
        };
        Pattern pat = Pattern.compile(&quot;(?!&quot; + regexInvalida + &quot;)&quot; + regexValida, Pattern.CASE_INSENSITIVE);
        for (int i = 0; i &lt; test.length; ++i) {
            System .out .println (&quot;{&quot; + test[i] + &quot;} : &quot; + pat.matcher(test[i]).matches());
        }
    }
}

Aham, o exemplo abaixo é um pouco mais fácil de compreender. Eu quero que a expressão regular bata com “< img src= alguma coisa”, mas não com as "< img src = “/WBCM”. Eu postei este exemplo há algum tempo atrás.

import java.util.regex.*;
import java.util.*;

class TesteExcetoWBCM {
    public static void main(String[] args) {
    String[] testes = {
"<img src=\"/WBCM/locais/imagens/nada.gif\" alt=\"\" width=\"21\" height=\"1\" border=\"0\">",
"<img src=\"/WBCM/imagens/ico_xdb_off.gif\" title=\"Exclui item\" name=\"ico_x<bean:write name=\"autorizacao\" property='id' />",
"<img src=\"/WBCM/imagens/plastic.gif\" alt=\"\" width=\"1\" height=\"21\" border=\"0\">",
"<img src=\"/WBCM/imagens/web_inactivate.gif\" title=\"Clique aqui para desativar este usuário\" name=\"ico_x<bean:write name='oUsuario' property='id' />",
"<img src=\"/webcomm/WBCM/AIT/consulta2aViaDetalhe.do?method=detalheCodeBars&code=<bean:write name=\"oDocumentoNotificacaoTO\" property=\"codigoBarras\" />",
"<img src=\"/webcomm/WBCM/AIT/consulta2aViaDetalhe.do?method=detalheCodeBarsLetras&code=<bean:write name=\"NumeroRH\" />",
"<img src='<tiles:getAsString name=\"icone\"/>",
    };
        String regexInvalida = "<img.*src=['\"](?!/WBCM/)[^>]*>";
        Pattern pat = Pattern.compile(regexInvalida, Pattern.CASE_INSENSITIVE);
        for (int i = 0; i < testes.length; ++i) {
            System .out .println ("{" + testes[i] + "} : " + pat.matcher(testes[i]).matches());
        }
    }
}

Ola thingol, tenho certeza que vc falou (?!, olha como tava a expressão no primeiro topico:

<UML[:]Class xmi.id = color=red/color(.*?)</UML[:]Class>

Vou dar uma olhada no que vc escreveu…
obrigado