У меня есть такие URL-адреса:
/domain.com/segment1/segment2/segment3/segment4/segment5/segment6/segment7/filename.ext
Иногда
http://someother.com/segment1/segment2/segment3/segment4/segment5/segment6/segment7/filename.ext
Мне нужно извлечь сегмент 6 специально с помощью C# и Regex. Регулярное выражение является абсолютным требованием, поскольку в будущем я мог бы захотеть извлечь сегмент 3, просто изменив некоторую конфигурацию.
В .Net есть класс Uri
, разработанный специально для разбора URI. Регулярные выражения не кажутся мне подходящим инструментом для этой работы.
«Регулярное выражение является абсолютным требованием, так как я мог бы захотеть извлечь сегмент 3 в будущем, просто изменив некоторую конфигурацию». Я бы сказал, что вы можете сделать это практически с любым методом извлечения (например, string.Split)
Или, если вам нужно решение C#, если это так: dotnetfiddle.net/tSWDO6. Также обратите внимание, что вы можете поместить регулярное выражение в свою конфигурацию в соответствии с вашими потребностями.
new Uri(...).LocalPath.Split('/')[6]
намного надежнее, чем Regex.
Мое требование было С# + Regex. Regex было абсолютным требованием. Uri будет работать в фиксированном контексте. Я не в таком контексте.
Попробуйте регулярное выражение: (?<=\.com)(?:/([^/]+))+/[^/.]+?\.\w+
В .NET есть класс UriTemplate
(Эми уже упомянула Uri
в комментариях). Существует множество аспектов сопоставления URL-адресов (например, чувствительность к регистру, отслеживание косой черты по сравнению с отсутствием завершающей косой черты и т. д.), которые могут сделать задачу поиск подходящего регулярного выражения чрезмерно сложной.
UriTemplate может работать со многими из этих вещей «из коробки». Может быть, вы можете использовать это для подхода типа «разделяй и властвуй».
Uri baseUri = new Uri("http://someother.com");
UriTemplate template
= new UriTemplate("segment1}/{segment2}/{segment3}/{segment4}/{segment5}/{segment6}/{segment7}/{filename}");
Uri fullUri
= new Uri("http://someother.com/super1/kali2/fragi3/listig4/expi5/ali6/docious7/filename.ext");
UriTemplateMatch results = template.Match(baseUri, fullUri);
if (results.BoundVariables["segment6"]) {
WriteLine(results.BoundVariables["segment6"]);
// Output: "ali6"
// further regex matching can take place here
}
Взгляните на Справочная документация по .NET для получения дополнительной информации.
Хотя вам лучше использовать классы, связанные с URL-адресом, для анализа URL-адреса, как объяснено в другом ответе, поскольку встроенные функции проверены и хорошо протестированы для обработки даже крайних случаев, но, как вы упомянули, у вас есть некоторые ограничения и вы можете использовать только решение регулярного выражения, вы можете попробовать следующее решение.
Поиск шестого или N-го сегмента можно легко выполнить с помощью этого регулярного выражения,
(?:([^/]+)/){7}
который захватывает 6+1 (N+1 в целом для N-го сегмента, где +1 соответствует доменной части URL-адреса) сегментов, и группа сохраняет последнее захваченное значение, к которому можно получить доступ с помощью group1.
Здесь ([^/]+)
соответствует одному или нескольким любым символам, кроме /
, и захватывает содержимое в группе 1, за которой следует /
, и все это совпадает ровно 7 раз.
Демонстрация регулярных выражений
var pattern = "(?:([^/]+)/){7}";
var match = Regex.Match("/domain.com/segment1/segment2/segment3/segment4/segment5/segment6/segment7/filename.ext", pattern);
Console.WriteLine("Segment: " + match.Groups[1].Value);
match = Regex.Match("http://someother.com/segment1/segment2/segment3/segment4/segment5/segment6/segment7/filename.ext", pattern);
Console.WriteLine("Segment: " + match.Groups[1].Value);
Выводит значение шестого сегмента,
Segment: segment6
Segment: segment6
Спасибо. Вот оно. Я не мог использовать класс Uri. Вот почему я указал, что Regex является абсолютным требованием.
что ты уже испробовал?