2016-02-24 3 views
1

Я пытаюсь проанализировать заданную строку, которая является доброй дорожкой, разделенной /. Мне нужно написать регулярное выражение, которое будет соответствовать каждому сегменту в пути к соответствующей группе регулярных выражений.Регулярное выражение с необязательными сопоставимыми группами

Пример 1:

вход:

/EAN/SomeBrand/appliances/refrigerators/RF444

выход:

Group: producer, Value: SomeBrand Group: category, Value: appliances Group: subcategory, Value: refrigerators Group: product, Value: RF4441

Пример 2:

вход:

/EAN/SomeBrand/appliances

выход:

Group: producer, Value: SomeBrand Group: category, Value: appliances Group: subcategory, Value: Group: product, Value:

Я попытался следующий код, он отлично работает, когда путь полон (как и в первом exmaple), но не смог найти групп, когда входная строка является беспристрастной (как в примере 2).

static void Main() 
{ 
    var pattern = @"^" + @"/EAN" 
       + @"/" + @"(?<producer>.+)" 
       + @"/" + @"(?<category>.+)" 
       + @"/" + @"(?<subcategory>.+)" 
       + @"/" + @"(?<product>.+)?" 
       + @"$"; 

    var rgx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); 
    var result = rgx.Match(@"/EAN/SomeBrand/appliances/refrigerators/RF444"); 

    foreach (string groupName in rgx.GetGroupNames()) 
    { 
    Console.WriteLine(
     "Group: {0}, Value: {1}", 
     groupName, 
     result.Groups[groupName].Value); 
    } 


    Console.ReadLine(); 
} 

Любое предложение приветствуется. К сожалению, я не могу просто разбить строку, поскольку используемая среда ожидает объект regex.

+0

Означает ли это, что все ваши детали (в том числе «производитель» и «категория») являются необязательными? –

ответ

1

Попробуйте

var pattern = @"^" + @"/EAN" 
    + @"(?:/" + @"(?<producer>[^/]+))?" 
    + @"(?:/" + @"(?<category>[^/]+))?" 
    + @"(?:/" + @"(?<subcategory>[^/]+))?" 
    + @"(?:/" + @"(?<product>[^/]+))?"; 

Обратите внимание, как я заменил . с [^/], потому что вы хотите использовать / для разделения строк. Обратите внимание даже на использование необязательного квантификатора для каждой подчасти (?)

2

Вы можете использовать дополнительные группы (...)? и заменить .+ жадных шаблоны соответствия точек с отрицаниями символьных классами [^/]+:

^/EAN/(?<producer>[^/]+)/(?<category>[^/]+)(/(?<subcategory>[^/]+))?(/(?<product>[^/]+))?$ 
             ^     ^^^     ^^ 

Смотрите regex demo

Это, как вы должны объявить регулярное выражение в C# код:

var pattern = @"^" + @"/EAN" 
      + @"/(?<producer>[^/]+)" 
      + @"/(?<category>[^/]+)" 
      + @"(/(?<subcategory>[^/]+))?" 
      + @"(/(?<product>[^/]+))?" 
      + @"$"; 

var rgx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); 

Примечание: Я использую регулярный захват группы как необязательные, но флаг RegexOptions.ExplicitCapture превращает все неименованные группы захвата в , не захватывая, и поэтому они не отображаются среди Match.Groups. Таким образом, мы имеем только 5 групп все время, даже без использования необязательных групп (?:...)?.

Смежные вопросы