Получить часть веб-адреса

Мне нужно извлечь фактическое имя файла из URL-адреса.

  • https://www.corp.com/lib/file.html?id=aa
  • https://www.corp.com/lib/file.html?id=aa/bb
  • https://www.corp.com/lib/file.html

Ожидаемый результат: file.html во всех случаях. Примечание. В имени файла не обязательно должна быть точка, это может быть просто file, и тогда в качестве результата должно вернуться file.

В случае

  • https://www.corp.com/lib/
  • https://www.corp.com/lib/?id=aa
  • https://www.corp.com/lib/?id=aa/bb

Ожидаемый результат должен быть ""

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

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

Есть идеи?

...какой язык вы используете? Практически в каждом языке есть библиотека для анализа URI. Вам следует использовать это вместо регулярного выражения, если это возможно, потому что в противном случае ваше регулярное выражение будет сбито с толку подстроками, похожими на имя файла, скажем, в части имени пользователя, или если есть имя хоста, похожее на имя файла - например. https://file.html:file.html:file.html/file.html/file.html?fi‌​lehtml=file.html — это действительный URI, понимаете (если file.html определен на вашем DNS-сервере)

Dai 21.08.2024 10:36

«Я не могу сделать это программно по шагам, потому что инструмент, который я использую, обрабатывает только регулярные выражения.»: что это за инструмент? Итак, это инструмент, который принимает, скажем, два аргумента: URL-адрес и регулярное выражение?

9769953 21.08.2024 10:38

@Dai На самом деле это не какой-то язык, это инструмент для расширения текста :-)

steb 21.08.2024 10:38

вот так: (?<=(?<!/)/)\w+\.\w+(?=$|\?)?

DuesserBaest 21.08.2024 10:39

Вас волнуют «неочевидные» URL-адреса, такие как https://corp.com/lib/? Или https://corp.com/lib/file.html/? Или https://corp.com/lib.

Joachim Sauer 21.08.2024 10:43

@JoachimSauer большое спасибо, что заметил это, моя вина! да, если «имя файла» отсутствует, то результатом должна быть пустая строка «». Я обновил вопрос.

steb 21.08.2024 10:46

@DuesserBaest, это так здорово :-) большое спасибо, я допустил ошибку в своем вопросе, очень извините. В имени файла не обязательно должна быть точка. в этом. Это может быть «corp.com/filename» без точки. Очень сожалею о пропавшем футляре.

steb 21.08.2024 10:48

тогда откуда ты знаешь, что bb в https://www.corp.com/lib/?id=aa/bb не файл?

DuesserBaest 21.08.2024 10:49

@DuesserBaest необязательный знак вопроса и все, что следует за ним, всегда можно игнорировать. Извините за плохое описание.

steb 21.08.2024 10:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
9
62
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Проверьте, изменив URL-адрес с https://www.corp.com/lib/file.html на https://www.corp.com/lib/file надеюсь, что это сработает.

Ответ принят как подходящий

Пытаться:

^.*\K(?<=(?<!/)/)[.\w]+(?=\?)|([^?\n]*\?[^?\n]*)(*SKIP)(*FAIL)|[.\w]+$

См.: regex101


Объяснение:

есть три случая:

  1. файл находится перед ?:
  • ^.*\K: с начала строки сопоставить все и забыть, пока...
  • (?<!/)/)[.\w]+(?=\?): вы найдете строку, которой предшествует одна /, но не две // и за которой следует ?
  1. у тебя есть жало, содержащее ?
  • ([^?\n]*\?[^?\n]*): если строка содержит вопросительный знак...
  • (*SKIP)(*FAIL): выбрось это
  1. желаемое жало находится в конце строки:
  • [.\w]+$

Это очень хороший ответ :-) хотя я не совсем ясно изложил вопрос, в «имени файла» не обязательно должна быть точка. Верри, извините за плохое описание. Такое ощущение, что нужно просто изменить часть \w.\w, но потом она ломается и соответствует другим частям. :-)

steb 21.08.2024 11:05

@steb, можешь ли ты получить доступ к группам захвата? есть ли у вас доступ к группам сброса ветвей? попробуйте (?|^.*(?<=(?<!/)/)(\w+\.\w+)(?=\?)|([^?\n]*\?[^ ?\n]*)(*SKI‌​P)(*FAIL)|([.\w]+)$)‌​; результаты будут в группе 1

DuesserBaest 21.08.2024 11:07

Или, если вы можете использовать \K^.*\K(?<=(?<!/)/)[.\w]+(?=\?)|([^?\n]*\? [^?\n]*)(*SKIP)(*F‌​AIL)|[.\w]+$ будет работать

DuesserBaest 21.08.2024 11:09

Это УДИВИТЕЛЬНО, последний вариант с \K работает идеально. Огромное спасибо @DuesserBaest. Ты король регулярных выражений!

steb 21.08.2024 11:16

Его можно сократить до ^[^#?]*/\K[^/?#]*(?![^#?])

Casimir et Hippolyte 21.08.2024 11:24

@CasimiretHippolyte да, вы абсолютно правы, похоже, это тоже работает нормально :-) просто экранирует передние косые черты, и это работает в моем случае. Очень здорово получилось!

steb 21.08.2024 11:44

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

bobble bubble 21.08.2024 12:42

@bobblebubble у меня есть подозрения, что кто-то может отрицать многие мои ответы, но это нормально. Я отвечаю, чтобы помочь и научиться самому, а не ради хороших оценок или чего-то еще :) очень нравится ваш ответ - очень элегантно!

DuesserBaest 21.08.2024 12:46

Для использования с PCRE, возможно, этого будет достаточно:

^[^?]*/\K[\w.-]*

Посмотрите это демо по адресу regex101 (\n в демо предназначено только для многострочного тестирования)

Идея состоит в том, чтобы сопоставить любые символы , которые не являются ? до последней косой черты. С помощью \K сбросьте начало сообщаемого совпадения и оттуда сопоставьте любое количество слов-символов, точку, тире (также пустое).

Но если вы не хотите пустых совпадений и используете [\w.]+ , это не сработает (демо) из-за возврата. Чтобы это работало, вы можете использовать глагол PCRE COMMIT , чтобы не возвращаться после совпадения с последней косой чертой. Вероятно, вместо него можно использовать SKIP с аналогичным эффектом.

^[^?]*/(*COMMIT)\K[\w.-]+

Еще одно демо на regex101 (@DuesserBaest, я позаимствовал твою витрину)

Очень ясное и лаконичное регулярное выражение ++

anubhava 21.08.2024 12:45

@anubhava, спасибо! :)

bobble bubble 21.08.2024 12:46

Другие вопросы по теме