Regex: corresponde a tudo, menos ao padrão específico


310

Eu preciso de um regex capaz de corresponder a tudo, exceto uma string que comece com um padrão específico (especificamente index.phpe o que se segue, como index.php?id=2342343)


E qual padrão específico você deseja não corresponder?
— Dominic Rodger #

2
Existe uma razão pela qual você não pode corresponder ao seu padrão e não fazer algo se a string corresponder a isso?
— 9789 Thomas


@ Thomashowens: Depende. Depende de qual parte da expressão deve ser negada. Se toda a expressão deve ser negada, você entendeu. Por exemplo, se você quiser codificar "se a string não contiver 'Bruce' como uma substring, faça alguma coisa", você usaria claramente / Bruce / e colocaria a negação na instrução if, fora da regex . Mas pode ser que você queira negar alguma subexpressão. Digamos que você esteja procurando algo como o nome e sobrenome, onde o nome é Bruce e o sobrenome é tudo, exceto XYZ, onde XYZ é o sobrenome de uma celebridade chamada Bruce.
— mathheadinclouds

Respostas:


250

Não é um especialista em regexp, mas acho que você pode usar um lookahead negativo desde o início, por exemplo ^(?!foo).*$, não deve corresponder a nada do que começar foo.


7
Com grep, use -P para ativar o lookahead.
— Seppo Enarvi

Se não corresponde "foo" ou "bar" é o comportamento desejado, verifique esta resposta: stackoverflow.com/a/2404330/874824
— dave_k_smith

15
Esta resposta está errada, um teste rápido mostra isso. Eu acho que você quis dizer é ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
— gilad Mayani

4
Por favor, você poderia explicar os símbolos que usou e por que os usou?
— rotimi-best 14/05/19

339

Regex: corresponde a tudo, exceto :

Nota de demonstração : a nova linha \né usada nas classes de caracteres negados nas demos para evitar o estouro da correspondência com as linhas vizinhas. Eles não são necessários ao testar seqüências individuais.

Nota da âncora : Em muitas linguagens, use \Apara definir o início inequívoco da sequência e \z(no Python \Z, no JavaScript, $é bom) definir o final da sequência.

Nota de ponto : em muitos tipos (mas não em POSIX, TRE, TCL), .corresponde a qualquer caractere, exceto um caractere de nova linha . Certifique-se de usar um modificador DOTALL correspondente ( /sem PCRE / Boost / .NET / Python / Java e /mRuby) para .corresponder a qualquer caractere, incluindo uma nova linha.

Nota da barra invertida : nos idiomas em que é necessário declarar padrões com as seqüências C que permitem sequências de escape (como \npara uma nova linha), é necessário dobrar as barras invertidas com caracteres especiais para que o mecanismo possa tratá-los como caracteres literais (por exemplo, em Java, world\.será declarado como "world\\."ou use uma classe de caracteres:) "world[.]". Use literais de string bruto (Python r'\bworld\b'), literais de string literal C # @"world\."ou notações literais de strings / regex slashy como /world\./.


Grande escrever! Para o caso de "uma string (não) igual a alguma string", com o exemplo de ^(?!foo$), por que o cifrão precisa estar entre parênteses para que a expressão funcione? Eu esperava ^(?!foo)$dar os mesmos resultados, mas não dá.
— Grant Humphries

3
@GrantHumphries: Quando a $âncora está dentro do cabeçote, faz parte da condição, parte dessa afirmação de largura zero . Se estivesse do lado de fora, como dentro ^(?!foo)$, fará parte do padrão de consumo que exige o fim da sequência logo após o início da sequência, tornando irrelevante o cabeçote negativo negativo, pois sempre retornará verdadeiro (não pode haver texto após o final da sequência) , muito menos foo). Portanto, ^(?!foo$)corresponde ao início de uma sequência que não fooé seguida com a sequência final. ^(?!foo)$corresponde a uma sequência vazia.
— precisa saber é o seguinte

@ robots.txt Remova esses comentários. Você está fazendo uma pergunta XY. As classes de caracteres são destinadas a corresponder caracteres únicos; não há como definir uma sequência de caracteres com eles. Provavelmente, você deve encontrar a substring entre o início de uma string e a primeira ocorrência de cotou lane remover a correspondência, como regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
— Wiktor Stribiżew

Caro Wiktor. Você encerrou minha pergunta, mas sua resposta vinculada falha. Eu atualizei minha pergunta stackoverflow.com/questions/60004380/…
— MonsterMMORPG

Por exemplo, sua resposta vinculada falha neste exemplo "nos pacotes <! - e página da web <! - asdasasdas -> editores agora usam -> Lorem Ipsum"
— MonsterMMORPG

259

Você pode colocar um ^no início de um conjunto de caracteres para corresponder a qualquer coisa, menos esses caracteres.

[^=]*

vai combinar tudo, menos =


55
Isso é verdade, mas ele processa apenas um personagem de cada vez. Se você quiser excluir uma sequência de dois ou mais caracteres, precisará usar um lookahead negativo, como disseram os outros respondentes.
— 27613 Alan Moore

solução perfeita para remover qualquer caractere indesejável, exceto os do padrão. obrigado
— Sirmyself 30/01

@ Alan, "... você tem que usar um lookahead negativo ..." está incorreto, mas não devemos ser muito duros com você porque o Wiktor não postou sua resposta - o que mostra o porquê - até 2016.
— Cary Swoveland

6

Basta combinar /^index\.php/e rejeitar o que quer que seja.


Talvez escrito str !~ /\Aindex\.php/.
— Cary Swoveland

6

Em python:

>>> import re
>>> p='^(?!index\.php\?[0-9]+).*$'
>>> s1='index.php?12345'
>>> re.match(p,s1)
>>> s2='index.html?12345'
>>> re.match(p,s2)
<_sre.SRE_Match object at 0xb7d65fa8>

3
Isso rejeitará "index_php" ou "index # php".

1

Eu preciso de um poder regex para combinar tudo , mas , exceto uma string que começa com index.php um padrão específico (especificamente index.php eo que se segue, como index.php? Id = 2342343)

Use o método Exec

    let match,
        arr = [],
        myRe = /([\s\S]+?)(?:index\.php\?id.+)/g;

    var str = 'http://regular-viragenia/index.php?id=2342343';

    while ((match = myRe.exec(str)) != null) {
         arr.push(match[1]);
    } 
    
    console.log(arr);

var myRe = /([\s\S]+?)(?:index\.php\?id=.+)/g;
var str = 'http://regular-viragenia/index.php?id=2342343';
var matches_array = myRe.exec(str);
console.log(matches_array[1]);

OU OUTRO JOGO

let match,
            arr = [],
            myRe = /index.php\?id=((?:(?!index)[\s\S])*)/g;

        var str = 'http://regular-viragenia/index.php?id=2342343index.php?id=111index.php?id=222';

        while ((match = myRe.exec(str)) != null) {
             arr.push(match[1]);
        } 

        console.log(arr);


-13

Que tal não usar regex:

// In PHP
0 !== strpos($string, 'index.php')

11
O OP solicitou especificamente uma regex ... Não sei se isso ajuda! (Ele pode estar usando grepna linha de comando, por exemplo, ou Perl / Python / qualquer outra linguagem, ou um comando "Executar este regex para cada linha" em um editor de texto, etc ...)
— rinogo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.