Regex não operador

109

Existe um operador NOT no Regexes? Como naquela string:"(2001) (asdf) (dasd1123_asd 21.01.2011 zqge)(dzqge) name (20019)"

Eu quero excluir todos \([0-9a-zA-z _\.\-:]*\), mas não aquele onde é um ano: (2001).

Então, o que a regex deve retornar deve ser: (2001) name.

NOTA: algo como \((?![\d]){4}[0-9a-zA-z _\.\-:]*\)não funciona para mim (de (20019)alguma forma também corresponde ...)

Sonnenhut
fonte
1
Há uma String como acima e quero regex-lo, que o resultado do regex é: (2001) name.
Sonnenhut

Respostas:

112

Não, não há nenhuma operadora direta. Pelo menos não da maneira que você espera.

Você pode usar um lookahead negativo de largura zero, no entanto:

\((?!2001)[0-9a-zA-z _\.\-:]*\)

A (?!...)parte significa "apenas corresponde se o texto a seguir (daí: lookahead) não (daí: negativo) corresponder a isso. Mas, na verdade, não consome os caracteres aos quais corresponde (daí: largura zero).

Na verdade, existem 4 combinações de lookarounds com 2 eixos:

  • lookbehind / lookahead: especifica se os caracteres antes ou depois do ponto são considerados
  • positivo / negativo: especifica se os caracteres devem corresponder ou não .
Joachim Sauer
fonte
Obrigado o?! é o que eu estava sugerindo também, mas de qualquer forma, se eu usar \((?![\d]{4})[0-9a-zA-z _\.\-:]+\), ainda está (20019)nele
Sonnenhut
Na edição da sua pergunta você colocou o {4} fora do lookahead e neste comentário você colocou dentro : qual você tentou? Além disso: se quiser (20019)corresponder, você deve adicionar o \) interior da sua antevisão:\((?![\d]{4}\))[0-9a-zA-z _\.\-:]+\)
Joachim Sauer
Com a regex acima em seu comentário, funciona. Mas eu não entendo isso ... não entendo porque você foge da parte seguinte \((?![\d]{4} -->\)<--)[0-9a-zA-z _\.\-:]+\)Aí tem um colchete que não está fechado, não é?
Sonnenhut
Eu escapei do parêntese de fechamento )porque desejo corresponder ao caractere literal) (assim como você faz no início e no final de sua regex!). Então, depois de combinar isso, termino a análise à frente usando um sem escape ).
Joachim Sauer
Entendi. Fiquei um pouco confuso com todos aqueles personagens. Obrigado.
Sonnenhut
183

Não exatamente, embora geralmente você possa usar alguma solução alternativa em um dos formulários

  • [^abc], que é caractere por caractere não aou bou c,
  • ou lookahead negativo:, a(?!b)que anão é seguido porb
  • ou lookbehind negativo:, (?<!a)bque bnão é precedido pora
Johan Sjöberg
fonte
Sim, eu acho negativo olhar-behind é b - referência (<a?!): Regular-expressions.info/lookaround.html
Jankins
8
Mas [^abc]deve significar não aou bou c, não "não a string abc".
Chovendo