Логическое ИЛИ не работает в регулярном выражении
Я работаю над большим файлом журнала, записи которого следующие:
-- "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*.*?(?= |\?)
Вы могли бы использовать группы захвата ()
, чтобы захватить соответствующие строки.
(?<=GET |POST )\s*(.*?)(?= |\?)
Объяснение:
(?<= 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