Nem todos os tipos de expressões regulares podem fazer isso. Em que ambiente você está trabalhando? Java? Perl? .INTERNET? Alguma biblioteca regex C / C ++? Um RDBMS?
FrustratedWithFormsDesigner
8
Você não diz o que deseja, mas pode simplesmente inverter o sentido da operação de "correspondência". Isso não ajudará se você estiver tentando fazer extração nas partes não correspondentes, mas para testar se uma string excluída não está presente, funcionaria: if (!s.match(/red|green|blue/)) ... Nota: eu sei que o OP não especifica qual linguagem / estrutura, então o anterior deve ser considerado um exemplo genérico, não prescritivo.
tvanfosson
Respostas:
153
Se você quiser ter certeza de que o barbante não é vermelho, verde ou azul, a resposta de caskey é esta. O que geralmente se deseja, no entanto, é certificar-se de que a linha não contenha vermelho, verde ou azul em qualquer lugar dela. Para isso, ancore a expressão regular com ^e inclua .*na antevisão negativa:
^(?!.*(red|green|blue))
Além disso, suponha que você queira linhas contendo a palavra "motor", mas sem nenhuma dessas cores:
^(?!.*(red|green|blue)).*engine
Você pode pensar que pode fatorar o .*para o início da expressão regular:
^.*(?!red|green|blue)engine # Does not work
Mas você não pode. Você precisa ter as duas instâncias de .*para que funcione.
@caskey, A resposta completa é uma combinação minha e sua. Se você quiser mesclá-los, excluirei o meu.
Wayne Conrad,
13
Essa resposta seria muito mais útil se você a explicasse um pouco. Por exemplo: O que fazer "?" e "!" significar? Por que você precisa de grupos de captura?
Lii
É Python válido também.
Joe Mornin
apenas usei isso com a biblioteca Delphi regEx e só funciona assim: ^ (?! vermelho | verde | azul). Também é válido para testá-lo em regex101.com . Portanto, o erro de digitação acima está faltando um ^ ou realmente funciona assim em Java / Perl / Python ..?
Peter
32
Combinando qualquer coisa, exceto strings fornecidas
Se você deseja combinar toda a string onde deseja combinar tudo, mas certas strings, você pode fazer assim:
^(?!(red|green|blue)$).*$
Isso diz, comece a correspondência do início da string onde ela não pode começar e terminar com vermelho, verde ou azul e corresponder a qualquer outra coisa ao final da string.
Você pode reduzir drasticamente a contagem de passos trocando [\ s \ S] por um ponto. Fiquei muito confuso por que, aparentemente, todos os outros exemplos capturam cada palavra individualmente. Dessa forma, é um pouco mais etapas regex, mas requer muito menos pós-processamento.
Zatronium de
3
mas isso não faz correspondência (validação de texto), apenas remove o texto especificado durante a substituição.
Marek R de
Esta solução não produzirá a parte final do texto após as palavras conhecidas. Então, não há necessidade de comparar a velocidade, ela está errada.
Wiktor Stribiżew
@ WiktorStribiżew fixed.
hlcs
10
Tive a mesma dúvida, as soluções propostas estavam quase a funcionar mas apresentavam alguns problemas. No final, a regex que usei é:
^(?!red|green|blue).*
Testei em Javascript e .NET.
. * não deve ser colocado dentro do lookahead negativo como este: ^ (?!. * red | green | blue) ou faria o primeiro elemento se comportar de forma diferente do resto (ou seja, "outro vermelho" não seria correspondido enquanto " outro verde "seria)
A correspondência de qualquer texto, exceto aqueles que correspondem a um padrão, geralmente é obtida com a divisão da string com o padrão regex .
Exemplos :
c #- Regex.Split(text, @"red|green|blue")ou, para se livrar de valores vazios, Regex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x))(veja demo )
vb.net- Regex.Split(text, "red|green|blue")ou, para remover itens vazios, Regex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s))(consulte a demonstração ou esta demonstração onde LINQ é compatível)
javascript- text.split(/red|green|blue/)(não há necessidade de usar o gmodificador aqui!) (para se livrar dos valores vazios, use text.split(/red|green|blue/).filter(Boolean)), veja a demonstração
Java- text.split("red|green|blue"), ou - para manter todos os itens vazios - use text.split("red|green|blue", -1), ou para remover todos os itens vazios, use mais código para removê-los (veja a demonstração )
descolado- Semelhante ao Java, text.split(/red|green|blue/)para fazer com que todos os itens finais sejam usados text.split(/red|green|blue/, -1)e para remover todos os itens vazios usados text.split(/red|green|blue/).findAll {it != ""})(veja demo )
Kotlin- text.split(Regex("red|green|blue"))ou, para remover itens em branco, use text.split(Regex("red|green|blue")).filter{ !it.isBlank() }, consulte a demonstração
escala- text.split("red|green|blue"), ou para manter todos os itens vazios no final, use text.split("red|green|blue", -1)e para remover todos os itens vazios, use text.split("red|green|blue").filter(_.nonEmpty)(ver demonstração )
rubi- text.split(/red|green|blue/), para se livrar de valores vazios, use .split(/red|green|blue/).reject(&:empty?)(e para obter itens vazios à esquerda e à direita, use -1como o segundo argumento .split(/red|green|blue/, -1)) (consulte a demonstração )
perl- my @result1 = split /red|green|blue/, $text;, ou com todos os itens vazios à direita my @result2 = split /red|green|blue/, $text, -1;, ou sem quaisquer itens vazios, my @result3 = grep { /\S/ } split /red|green|blue/, $text;(veja a demonstração )
ir- Use regexp.MustCompile("red|green|blue").Split(text, -1), e se você precisar remover itens vazios, use este código . Veja a demonstração do Go .
NOTA : Se seus padrões contiverem grupos de captura , as funções / métodos de divisão de regex podem se comportar de maneira diferente, dependendo também de opções adicionais. Consulte então a documentação do método de divisão apropriada.
if (!s.match(/red|green|blue/)) ...
Nota: eu sei que o OP não especifica qual linguagem / estrutura, então o anterior deve ser considerado um exemplo genérico, não prescritivo.Respostas:
Se você quiser ter certeza de que o barbante não é vermelho, verde ou azul, a resposta de caskey é esta. O que geralmente se deseja, no entanto, é certificar-se de que a linha não contenha vermelho, verde ou azul em qualquer lugar dela. Para isso, ancore a expressão regular com
^
e inclua.*
na antevisão negativa:Além disso, suponha que você queira linhas contendo a palavra "motor", mas sem nenhuma dessas cores:
Você pode pensar que pode fatorar o
.*
para o início da expressão regular:Mas você não pode. Você precisa ter as duas instâncias de
.*
para que funcione.fonte
Depende do idioma, mas geralmente existem afirmações negativas que você pode colocar assim:
(Obrigado pela correção de sintaxe, o acima é Java e Perl válidos, YMMV)
fonte
Combinando qualquer coisa, exceto strings fornecidas
Se você deseja combinar toda a string onde deseja combinar tudo, mas certas strings, você pode fazer assim:
^(?!(red|green|blue)$).*$
Isso diz, comece a correspondência do início da string onde ela não pode começar e terminar com vermelho, verde ou azul e corresponder a qualquer outra coisa ao final da string.
Você pode tentar aqui: https://regex101.com/r/rMbYHz/2
Observe que isso só funciona com mecanismos regex que suportam uma antecipação negativa .
fonte
Você não precisa de antecipação negativa. Há um exemplo de trabalho:
Descrição:
[\s\S]
- corresponde a qualquer personagem*
- corresponde de 0 a ilimitado do grupo anterior?
- corresponder o menos possível(red|green|blue|)
- corresponde a uma destas palavras ou nadag
- repetir padrãoExemplo:
whiteredwhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredwhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredredgreenredgreenredgreenredgreenredgreenbluewhiteredbluewhiteredbluewhiteredbluewhiteredbluewhiteredwhite
Será:
whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite
Teste-o:
regex101.com
fonte
Tive a mesma dúvida, as soluções propostas estavam quase a funcionar mas apresentavam alguns problemas. No final, a regex que usei é:
Testei em Javascript e .NET.
. * não deve ser colocado dentro do lookahead negativo como este: ^ (?!. * red | green | blue) ou faria o primeiro elemento se comportar de forma diferente do resto (ou seja, "outro vermelho" não seria correspondido enquanto " outro verde "seria)
fonte
A correspondência de qualquer texto, exceto aqueles que correspondem a um padrão, geralmente é obtida com a divisão da string com o padrão regex .
Exemplos :
Regex.Split(text, @"red|green|blue")
ou, para se livrar de valores vazios,Regex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x))
(veja demo )Regex.Split(text, "red|green|blue")
ou, para remover itens vazios,Regex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s))
(consulte a demonstração ou esta demonstração onde LINQ é compatível)text.split(/red|green|blue/)
(não há necessidade de usar og
modificador aqui!) (para se livrar dos valores vazios, usetext.split(/red|green|blue/).filter(Boolean)
), veja a demonstraçãotext.split("red|green|blue")
, ou - para manter todos os itens vazios - usetext.split("red|green|blue", -1)
, ou para remover todos os itens vazios, use mais código para removê-los (veja a demonstração )text.split(/red|green|blue/)
para fazer com que todos os itens finais sejam usadostext.split(/red|green|blue/, -1)
e para remover todos os itens vazios usadostext.split(/red|green|blue/).findAll {it != ""})
(veja demo )text.split(Regex("red|green|blue"))
ou, para remover itens em branco, usetext.split(Regex("red|green|blue")).filter{ !it.isBlank() }
, consulte a demonstraçãotext.split("red|green|blue")
, ou para manter todos os itens vazios no final, usetext.split("red|green|blue", -1)
e para remover todos os itens vazios, usetext.split("red|green|blue").filter(_.nonEmpty)
(ver demonstração )text.split(/red|green|blue/)
, para se livrar de valores vazios, use.split(/red|green|blue/).reject(&:empty?)
(e para obter itens vazios à esquerda e à direita, use-1
como o segundo argumento.split(/red|green|blue/, -1)
) (consulte a demonstração )my @result1 = split /red|green|blue/, $text;
, ou com todos os itens vazios à direitamy @result2 = split /red|green|blue/, $text, -1;
, ou sem quaisquer itens vazios,my @result3 = grep { /\S/ } split /red|green|blue/, $text;
(veja a demonstração )preg_split('~red|green|blue~', $text)
oupreg_split('~red|green|blue~', $text, -1, PREG_SPLIT_NO_EMPTY)
para não produzir itens vazios (ver demonstração )re.split(r'red|green|blue', text)
ou, para remover itens vazios,list(filter(None, re.split(r'red|green|blue', text)))
(ver demonstração )regexp.MustCompile("red|green|blue").Split(text, -1)
, e se você precisar remover itens vazios, use este código . Veja a demonstração do Go .NOTA : Se seus padrões contiverem grupos de captura , as funções / métodos de divisão de regex podem se comportar de maneira diferente, dependendo também de opções adicionais. Consulte então a documentação do método de divisão apropriada.
fonte
Todos exceto a palavra "vermelho"
Todos exceto a palavra "vermelho"
fonte