Como negar todo o regex?


95

Eu tenho uma regex, por exemplo (ma|(t){1}). Corresponde a mae te não correspondebla .

Eu quero negar a regex, portanto, ela deve corresponder blae não mae t, adicionando algo a esta regex . Eu sei que posso escrever bla, mas o regex real é mais complexo.


5
Como um aparte, {1}é completamente inútil. (Se você acha que fornece algum valor, por que não escreve ((m{1}a{1}){1}|(t){1}){1}?)
tripleee

Respostas:


100

Use lookaround negativo: (?!pattern)

Lookarounds positivos podem ser usados ​​para afirmar que um padrão corresponde. Lookarounds negativo é o oposto: é usado para afirmar que um padrão NÃO corresponde. Alguns sabores apóiam afirmações; alguns colocam limitações no olhar para trás, etc.

Links para regular-expressions.info

Veja também

Mais exemplos

Essas são tentativas de criar soluções regex para problemas de brinquedos como exercícios; eles devem ser educacionais se você está tentando aprender as várias maneiras de usar lookarounds (aninhando-os, usando-os para capturar, etc):


2
regular-expressions.info é um ótimo recurso para todas as coisas de regex.
Freiheit

O que todos têm suporte visual ? Não funciona com grep.
Lazer

Pattern.compile("(?!(a.*b))").matcher("xab").matches()deve ser true, certo?
Karl Richter

4
Parece que não está certo, consulte stackoverflow.com/questions/8610743/… para uma alternativa correta.
Karl Richter

56

Supondo que você só deseja proibir strings que correspondam completamente à regex (ou seja, mmblaestá tudo bem, mas mmnão é), isso é o que você deseja:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)é uma antevisão negativa ; ele diz "começando da posição atual, os próximos caracteres não são mmou t, seguidos pelo final da string." A âncora inicial ( ^) no início garante que o lookahead seja aplicado no início da string. Se der certo, o .*segue e consome a string.

Para sua informação, se você estiver usando o matches()método Java , você realmente não precisa do the ^e do final $, mas eles não causam nenhum dano. No $entanto, o interior do lookahead é obrigatório.


2
A parte mais útil desta resposta é que você precisa adicionar .*ao final de sua regex, caso contrário, todas as strings serão rejeitadas.
Rav

2
O $ interior do lookahead negativo E o .*no final são ambos bits críticos. Como sempre com REs, um forte conjunto de testes de unidade é absolutamente crítico para acertar. Esta resposta está 100% correta.
Tom Dibble

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

isso é para a regex fornecida.
the \ b é encontrar o limite da palavra.
o olhar positivo à frente (? = \ w) está aqui para evitar espaços.
a análise negativa da regex original é evitar correspondências dela.
e finalmente o (\ w *) serve para capturar todas as palavras que sobraram.
o grupo que conterá as palavras é o grupo 3.
o simples (?! padrão) não funcionará, pois qualquer subcadeia corresponderá
ao simples ^ (?! (?: m {2} | t) $). * $ será não funciona, pois sua granularidade é linhas completas


0

Aplique se você usar laravel.

O Laravel possui um not_regex onde o campo sob validação não deve corresponder à expressão regular fornecida; usa a preg_matchfunção PHP internamente.

'email' => 'not_regex:/^.+$/i'
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.