Как бы вы использовали регулярное выражение, чтобы игнорировать строки, содержащие определенную подстроку? - PullRequest
4 голосов
/ 10 февраля 2009

Как мне использовать отрицательное lookbehind (или любой другой метод) регулярное выражение для игнорирования строк, содержащих определенную подстроку?

Я прочитал два предыдущих вопроса stackoverflow:
Java-регулярное_выражение-для-фильтрации файлов
регулярное выражение к игре-против-то-что-это-не-а-Specific-подстроки

Они почти , что я хочу ... моя проблема в том, что строка не заканчивается тем, что я хочу игнорировать. Если бы это произошло, это не было бы проблемой.

У меня такое ощущение, что это связано с тем, что обходные пути имеют нулевую ширину и что-то совпадает при втором проходе через строку ... но я не слишком уверен во внутренних органах.

В любом случае, если кто-то захочет взять время и объяснить его, я буду очень признателен.

Вот пример входной строки, которую я хочу игнорировать:

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

Вот пример входной строки, которую я хочу сохранить для дальнейшей оценки:

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

Ключевым моментом для меня является то, что я хочу игнорировать любой HTTP GET, который идет после корневой страницы документа по умолчанию.

Вот мой маленький тестовый комплект и лучший RegEx, который я когда-либо придумал.

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();
}
}

Ответы [ 4 ]

4 голосов
/ 10 февраля 2009

Не могли бы вы просто сопоставить любой путь, который не заканчивается /

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

Это также можно сделать, используя отрицательный взгляд назад

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

Здесь (?<!/) говорит "последовательность , предшествующая , должна не соответствовать /".

1 голос
/ 10 февраля 2009

Может быть, я что-то здесь упускаю, но не могли бы вы просто обойтись без регулярного выражения и игнорировать все, для чего это верно:

string.contains("/ HTTP")

Поскольку путь к файлу никогда не заканчивается косой чертой.

0 голосов
/ 10 февраля 2009

Если вы пишете Regex для этого комплекса, я бы порекомендовал создать библиотеку ресурсов вне StackOverflow.

0 голосов
/ 10 февраля 2009

Я бы использовал что-то вроде этого:

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

Это соответствует каждому пути, который не просто /FOO/BAR/.

...