Как бы вы использовали регулярное выражение, чтобы игнорировать строки, содержащие определенную подстроку?
-
22-08-2019 - |
Вопрос
Как мне использовать регулярное выражение отрицательного просмотра (или любого другого метода), чтобы игнорировать строки, содержащие определенную подстроку?
Я прочитал два предыдущих вопроса о stackoverflow:
Java-regexp-для-фильтрации файлов
регулярное выражение для сопоставления с чем-то, что не является конкретной подстрокой
Они есть около что я хочу...моя проблема в том, что строка не заканчивается тем, что я хочу игнорировать.Если бы это было так, это не было бы проблемой.
У меня такое ощущение, что это связано с тем фактом, что обходные пути имеют нулевую ширину и что-то совпадает при втором проходе по строке...но я не слишком уверен во внутренностях.
В любом случае, если кто-то захочет потратить время и объяснить это, я буду очень признателен.
Вот пример входной строки, которую я хочу игнорировать:
192.168.1.10 - - [08.02.2009:16:33:54 -0800] "GET /FOO/BAR/HTTP/1.1" 200 2246
Вот пример входной строки, которую я хочу сохранить для дальнейшей оценки:
192.168.1.10 - - [08.02.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();
}
}
Решение
Не могли бы вы просто сопоставить любой путь, который не заканчивается на /
String inRegEx = "^.* \"GET (.*[^/]) HTTP/.*$";
Это также можно сделать с помощью негативный взгляд назад
String inRegEx = "^.* \"GET (.+)(?<!/) HTTP/.*$";
Здесь, (?<!/)
говорит: « предшествующий последовательность должна нет соответствовать /
".
Другие советы
Возможно, я что-то здесь упускаю, но не могли бы вы просто обойтись без регулярных выражений и игнорировать все, для чего это верно:
string.contains("/ HTTP")
Потому что путь к файлу никогда не заканчивается косой чертой.
Я бы использовал что-то вроде этого:
"\"GET /FOO/BAR/[^ ]+ HTTP/1\.[01]\""
Это соответствует каждому пути, который не просто /FOO/BAR/
.
Если вы пишете такое сложное выражение Regex, я бы рекомендовал создать библиотеку ресурсов за пределами StackOverflow.