Como você usar uma expressão regular para ignorar seqüências que contêm uma substring específica?

StackOverflow https://stackoverflow.com/questions/530441

  •  22-08-2019
  •  | 
  •  

Pergunta

Como eu iria sobre como usar um lookbehind negativo (ou qualquer outro método) expressão regular para ignorar strings que contém uma subcadeia específica?

Eu li duas perguntas stackoverflow anteriores:
java-regexp-de-file-filtragem
regex-to-partida contra-algo- que-é-a-específica não-substring

Eles são quase o que eu quero ... o meu problema é a string não termina com o que eu quero ignorar. Se ele fez isso não seria um problema.

Tenho a sensação de que isso tem a ver com o fato de que lookarounds são de largura zero e algo está combinando na segunda passagem através da corda ... mas, eu sou nenhum muito certo dos internos.

De qualquer forma, se alguém está disposto a tomar o tempo e explicá-lo eu agradeceria muito.

Aqui está um exemplo de uma cadeia de entrada que eu quero ignorar:

192.168.1.10 - - [08 / fev / 2009: 16: 33: 54 -0800] "GET / foo / bar / HTTP / 1.1" 200 2246

Aqui está um exemplo de uma cadeia de entrada que eu quero manter para posterior avaliação:

192.168.1.10 - - [08 / fev / 2009: 16: 33: 54 -0800] "GET /FOO/BAR/content.js HTTP / 1.1" 200 2246

A chave para mim é que eu quero ignorar qualquer HTTP GET que está indo atrás de uma página padrão raiz do documento.

A seguir é o meu pequeno equipamento de teste ea melhor RegEx eu vim acima com a medida.

public static void main(String[] args){
String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/ HTTP/1.1\" 200 2246";
//String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/content.js HTTP/1.1\" 200 2246";
//String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/content.js HTTP/"; // This works
//String inString = "192.168.1.10 - - [08/Feb/2009:16:33:54 -0800] \"GET /FOO/BAR/ HTTP/"; // This works
String inRegEx = "^.*(?:GET).*$(?<!.?/ HTTP/)";
try {
  Pattern pattern = Pattern.compile(inRegEx);

  Matcher matcher = pattern.matcher(inString);

  if (matcher.find()) {
    System.out.printf("I found the text \"%s\" starting at " +
"index %d and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end());
  } else {
    System.out.printf("No match found.%n");
  }
} catch (PatternSyntaxException pse) {
  System.out.println("Invalid RegEx: " + inRegEx);
  pse.printStackTrace();
}
}
Foi útil?

Solução

Você poderia simplesmente corresponder a qualquer caminho que não termina com um /

String inRegEx = "^.* \"GET (.*[^/]) HTTP/.*$";

Isso também pode ser feito usando negativo lookbehind

String inRegEx = "^.* \"GET (.+)(?<!/) HTTP/.*$";

Aqui, (?<!/) diz que "o anterior seqüência deve não jogo /".

Outras dicas

Talvez eu estou faltando alguma coisa aqui, mas você não pode apenas ir sem qualquer expressão regular e ignorar qualquer coisa para a qual isto é verdade:

string.contains("/ HTTP")

Porque um caminho de arquivo nunca vai terminar com uma barra.

Gostaria de usar algo como isto:

"\"GET /FOO/BAR/[^ ]+ HTTP/1\.[01]\""

Esta corresponde a cada caminho que não é apenas /FOO/BAR/.

Se você estiver escrevendo Regex este complexo, eu recomendaria a construção de uma biblioteca de recursos fora do StackOverflow.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top