Логическое ИЛИ не работает в регулярном выражении

Я работаю над большим файлом журнала, записи которого следующие:

-- "GET <b>/fss-w3-mtpage.php</b> HTTP/1.1" 200 0.084 41 "-" "c110bc/1.0" 127.0.0.1:25001  0.084

-- "GET <b>/m/firstpage/Services/getAll</b>?ids=ABCVDFDS,ASDASBDB,ASDBSA&requestId=091fa2b4-643e-4473-b6d8-40210b775dcf HTTP/1.1" 200

-- POST <b>/lastpage/Services/getAll</b>?ids=ABCVDFDS,ASDASBDB,ASDBSA&requestId=091fa2b4-643e-4473-b6d8-40210b775dcf HTTP/1.1" 200

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

.*(POST|GET)\s+(([^\?]+)|([^\s])) 

Я хочу получить часть, которая после GET или же POST и до первого появления пространства ' ' или вопросительный знак '?',

проблема
Логическое ИЛИ в более поздней части регулярного выражения не работает. Если я использую только

.*(POST|GET)\s+([^\?]+)    

Я получаю правильную порцию, т.е. от GET или POST до первого знака вопроса '?', Точно так же, если я использую

.*(POST|GET)\s+([^\s]+)    

Я получаю правильную порцию, т.е. с GET или POST до первого пробела ' ').

Пожалуйста, кто-нибудь может сказать мне, где я не прав?

3 ответа

Решение

Получить сопоставленную группу из индекса 2

\b(POST|GET)\s+([^?\s]+)

Вот ДЕМО

Объяснение картины:

  \b                       the word boundary

  (                        group and capture to \1:
    POST                     'POST'
   |                        OR
    GET                      'GET'
  )                        end of \1

  \s+                      whitespace (\n, \r, \t, \f, and " ") (1 or more times)

  (                        group and capture to \2:

    [^?\s]+                  any character except: '?', whitespace
                             (\n, \r, \t, \f, and " ") (1 or more times)

  )                        end of \2

С [^\?]+ Я получаю правильную порцию до первого знака вопроса,
С [^\s]+ Я получаю правильную порцию до первого пробела

Потому что эти классы символов означают: все символы без пробелов или: все символы без пробелов.

Чтобы объединить их, вы хотите сказать: все символы, которые не являются ни знаком вопроса, ни пробелом:

[^?\s]+

С ИЛИ, которое вы использовали, он просто попробовал первый ([^\?]+ - в том числе пробелы), который удалось, и был бы возвращен и попытался [^\s]+ (включая вопросительные знаки) вместо этого, если первый не сработал.

Приведенное ниже регулярное выражение будет соответствовать только те строки, которые сразу после GET или же POST с последующим пробелом или ? условное обозначение.

(?<=GET |POST )\s*.*?(?= |\?)

DEMO

Вы могли бы использовать группы захвата (), чтобы захватить соответствующие строки.

(?<=GET |POST )\s*(.*?)(?= |\?)

DEMO

Объяснение:

(?<=                     look behind to see if there is:
  GET                      'GET '
 |                        OR
  POST                     'POST '
)                        end of look-behind
\s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                         more times)
(                        group and capture to \1:
  .*?                      any character except \n (0 or more
                           times)
)                        end of \1
(?=                      look ahead to see if there is:
                           ' '
 |                        OR
  \?                       '?'
)                        end of look-ahead
Другие вопросы по тегам