Регулярные выражения для соответствия 3 определенным местам строки

#c# #regex

#c# #регулярное выражение

Вопрос:

Я застрял, пытаясь найти способ получить 3 раздела строки без использования разделения и некоторых странных вещей. Целевая строка выглядит следующим образом:

 BLABLABLABLABLABLA BLABLABLA - BLABLA BLABLA (BLABLA1 BLABLA2)
  

Мне нужно извлечь три части следующим образом:

1) БЛАБЛАБЛАБЛАБЛАБЛАБЛА БЛАБЛАБЛА (левая часть)

2) БЛАБЛА-БЛАБЛА (средняя часть)

3) BLABLA1 BLABLA2 (правая часть в круглых скобках)

Что я уже сделал, так это:

 var text = "BLABLABLABLABLABLA BLABLABLA - BLABLA BLABLA (BLABLA1 BLABLA2)";

var left = Regex.Matches(text, @"([^)]*)-");
var middle = Regex.Matches(text, @"-([^)]*)(");
var right = Regex.Matches(text, @"(([^)]*))");

Console.WriteLine(left[0]);
Console.WriteLine(middle[0]);
Console.WriteLine(right[0]);
  

Вывод:

 BLABLABLABLABLABLA BLABLABLA -
- BLABLA BLABLA (
(BLABLA1 BLABLA2)
  

Кажется, работает, но вывод содержит разделители, и я просто хочу исходное содержимое.

Комментарии:

1. string.Split(new [] {'-','(',')')

2. @Общее отсутствует }

3. Используйте Regex.Split(s, @"s -s |s (([^()] ))$").Where(x => !string.IsNullOrWhiteSpace(x))

Ответ №1:

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

 ^(. )s -s (. )s (([^()] ))$
  

Объяснение:

  • ^ — Соответствует началу ввода
  • (. ) — Сопоставляет и фиксирует любой символ один или несколько раз и просто останавливается перед пробелом (ами) и дефисом и помещает в группу1
  • s -s — Сопоставляет пробелы, за которыми следует дефис - и снова пробелы, и исключает их из любого группового захвата, поскольку они не требуются
  • (. ) — Сопоставляет следующую последовательность символов одному или нескольким и записывает в группу2
  • s ( — Соответствует одному или нескольким пробелам, за которыми следует литерал (
  • ([^()] ) — Соответствует одному или нескольким любым символам, отличным от ( или ) , и записывается в group3
  • )$ — За которым следует литерал ) и конец строки

Демонстрация регулярных выражений

Демонстрация кода C #

 var text = "BLABLABLABLABLABLA BLABLABLA - BLABLA BLABLA (BLABLA1 BLABLA2)";

var match = Regex.Match(text, @"^(. )s -s (. )s (([^()] ))$");
Console.WriteLine("left: "   match.Groups[1].Value);
Console.WriteLine("middle: "   match.Groups[2].Value);
Console.WriteLine("right: "   match.Groups[3].Value);
  

С принтами,

 left: BLABLABLABLABLABLA BLABLABLA
middle: BLABLA BLABLA
right: BLABLA1 BLABLA2
  

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

 ^(. )s -s (. ?)s*(?:(([^()] )))?$
  

Демонстрация регулярных выражений с необязательной group3

Обновленная демонстрация C #

 var text = "BLABLABLABLABLABLA BLABLABLA - BLABLA BLABLA (BLABLA1 BLABLA2)";

var match = Regex.Match(text, @"^(. )s -s (. )s (([^()] ))$");
Console.WriteLine("left: "   match.Groups[1].Value);
Console.WriteLine("middle: "   match.Groups[2].Value);
Console.WriteLine("right: "   match.Groups[3].Value);

text = "BLABLABLABLABLABLA BLABLABLA - BLABLA BLABLA";

match = Regex.Match(text, @"^(. )s -s (. ?)s*(?:(([^()] )))?$");
Console.WriteLine("nleft: "   match.Groups[1].Value);
Console.WriteLine("middle: "   match.Groups[2].Value);
Console.WriteLine("right: "   match.Groups[3].Value);
  

С принтами,

 left: BLABLABLABLABLABLA BLABLABLA
middle: BLABLA BLABLA
right: BLABLA1 BLABLA2

left: BLABLABLABLABLABLA BLABLABLA
middle: BLABLA BLABLA
right:
  

Комментарии:

1. Не могли бы вы, пожалуйста, изменить это регулярное выражение, чтобы оно также соответствовало строке, которая не содержит правильной части, я только что заметил, что может произойти сценарий, некоторые строки содержат (), а другие нет

2. @AnonDev: Конечно, довольно просто. Просто нужно сделать эту группу необязательной, поместив ? в конец группы. Позвольте мне обновить мой пост.