Как улучшить это регулярное выражение для работы в других ситуациях? - PullRequest
0 голосов
/ 16 января 2019

Я могу разбить эту строку:

199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245

с этим RegEx:

'([(\d\.)]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

Итак, как улучшить этот RegEx, чтобы разделить строку такого типа (, где вместо IP-адреса ) есть адрес:

unicomp6.unicomp.net - - [01/Jul/1995:00:00:06 -0400] "GET /shuttle/countdown/ HTTP/1.0" 200 3985

и этот тип строки (, где между двойными кавычками стоят двойные кавычки, а у меня нет последнего числа )

frank.mtsu.edu - - [03/Jul/1995:02:41:15 -0400] "GET /images/" HTTP/1.0" 404 -

Спасибо!

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Я не знаю точно, что вы пытаетесь сделать, но ваше регулярное выражение не очень конкретное в его нынешнем виде. Ниже предложено решение того, что может быть улучшением. Это выглядит сложно, но на самом деле это не так уж и плохо, если разобраться.

^(\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b|\w+\.\w+\.(?:net|com|gov|edu))\s-\s-\s(\[[0-9]{2}\/\w{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}\s-[0-9]{4}\])\s(\"[^\"]+\")\s(.*)$

Проверьте https://regex101.com/r/ojIGIA/3, чтобы увидеть его в действии и для объяснений прочитайте правую панель.

Редактировать: Я понял, что пропустил ? в части IP-адреса регулярного выражения. Я также забыл экранировать ", так как я не принимал во внимание вкус Python. Исправлено и обновлено регулярное выражение и ссылка.

Теперь у меня есть немного больше времени, я немного подробнее объясню, что я сделал. Вышеуказанное регулярное выражение можно разделить следующим образом.
^ начало строки

( начало захвата группы 1

\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b Это захват IP-адреса. Зависит от того, насколько точным вы хотите быть, вы можете просто сделать что-то вроде \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}, если вы не слишком беспокоитесь об этом. Это также будет соответствовать всем действительным IP-адресам, но также будет соответствовать некоторым недействительным.

| ИЛИ оператор

\w+\.\w+\.(?:net|com|gov|edu) Это очень простой пример того, как может выглядеть захват URL.

) Конечная группа захвата 1

\s-\s-\s Соответствует вашему "- -" точно

(\[[0-9]{2}\/\w{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}\s-[0-9]{4}\]) Это мое предложение для съемки даты и других вещей в середине. Это нужно будет настроить в зависимости от того, что именно вы хотите. Это также группа захвата 2.

\s Пробел

(\"[^\"]+\") Соответствует всему, что находится в кавычках в этот момент матча. Группа захвата 3.

\s пробел

(.*) Соответствует всему остальному до конца и помещает в группу захвата 4.

$ Конец строки

Теперь это всего лишь предложения, поскольку я не знаю, что именно вы пытаетесь сделать, но, надеюсь, это поможет и даст вам некоторые идеи.

Одно замечание: я использую \ s вместо пробела. В использовании пробела нет ничего плохого, лично мне нравится использовать \ s, потому что мне легче читать.

0 голосов
/ 16 января 2019

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

'([(\d\.)]+|[a-z\d\.]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

Обратите внимание, что это предполагает, что все адреса состоят только из строчных букв, цифр и точек. РЕДАКТИРОВАТЬ: После @tripleee комментария я должен признать, что адреса могут содержать больше разных символов, поэтому я добавлю более терпимое решение:

'([(\d\.)]+|[^ ]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

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

'([^ ]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)'

Чтобы он работал с последним регистром, просто замените последний (\d+) на (\d+|-), как предложено @solarc ранее

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...