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)

pistacchio
fonte
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
2
Possível duplicata da expressão regular para corresponder a uma linha que não contém uma palavra?
precisa saber é o seguinte
@ 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.

Cat Plus Plus
fonte
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\./.

Wiktor Stribiżew
fonte
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 =

Firsh - LetsWP.io
fonte
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.


fonte
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>
AJ.
fonte
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);

Юрий Светлов
fonte
-13

Que tal não usar regex:

// In PHP
0 !== strpos($string, 'index.php')
Percutio
fonte
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