Строка группы регулярных выражений, в которой разделитель может использоваться дважды (регулярное выражение .net) - PullRequest
3 голосов
/ 26 марта 2019

Я пишу парсер для Excel, который может обновлять значения в документе.В настоящее время я анализирую верхний / нижний колонтитул формата документа электронной таблицы.Формат верхнего / нижнего колонтитула в Excel хранится в виде простого текста, разделенного следующим образом:

  • &L
  • &C
  • &R

Таким образом, ваш верхний / нижний колонтитул может выглядеть следующим образом в XML:

&LTodaysDate&CDocumentTitle&RAuthors Name

Если у вас есть только левый и правый заголовок, ваша строка XML будет выглядеть:

&LTodaysDate&RAuthors Name

Я попытался создать шаблон, который может обнаруживать каждую из этих групп и анализировать компонент (то есть &L, &C, &R) вдольс любым текстом, который появляется после этого тега.

Строка регулярного выражения: : (&.{1})([A-Za-z\d_ ]*) ( Ссылка на пример )

Однако у меня есть проблема с дополнительным регистром, которая будет означать, что я не могу правильно проанализировать заголовок Excel, содержащий амперсанды.

В заголовке Excel для вашего документа в заголовке указан амперсанд (этов текстовом формате) вы должны ввести &&.Таким образом, xml заголовка с амперсандами может выглядеть следующим образом:

&RPork && Beans (в таблице будет отображаться «Свинина и бобы»).

Мое регулярное выражение не может справиться спреждевременный амперсанд.В первой группе ((&.{1})) я прошу что-нибудь, что имеет амперсанд и символ, который следует за ним (то есть L / C / R).Как я могу сказать этой группе не включать, когда есть 2 амперсанда.Мои навыки регулярных выражений довольно новы, я могу описать то, что я хочу на более высоком уровне:

Я хочу разбить строку, где бы я ни увидел & L / & C / & R, и перехватить весь текст после этого, до другого & L /& C / & R разделитель (исключая новые пробелы и т. Д.).Я могу лучше всего описать это в C # linq ниже.

(&.{1}.Where(c => c != '&'))([A-Za-z\d_ ]*)

Для строки "& RPork && Beans"

мое регулярное выражение захватывает 2 совпадения, каждое с двумя группами:

соответствует 1 группа 1: «& R» группа 2: «свинина»

соответствует 2 группа 1: "&&" группа 2: "бобы"

, и я бы хотел, чтобы это совпадало один раз:группа 1: "& R" группа 2: "Свинина и бобы"

Спасибо за помощь

Ответы [ 2 ]

1 голос
/ 26 марта 2019

при моем понимании к делу я написал регулярное выражение, которое соответствует тому, что вам нужно ( Ссылка на пример )

и это выражение:

(& (? = [RCL]) [RCL] {1}) ([A-Za-z \ d_] (& (?! [RCL])) [A-Za- z \ d_] )

1 голос
/ 26 марта 2019

Вы можете использовать

var result = Regex.Split(s, "(&[LRC])").Where(x => !string.IsNullOrWhiteSpace(x));

См. Демоверсию regex .(&[LRC]) будет соответствовать & и буквам L, R или C после этого, это значение будет извлечено в результирующий массив из-за захвата скобок.

enter image description here

Другой пример использования :

var s = "&RPork && Beans&CDocument Title";
var result = Regex.Split(s, "(&[LRC])")
        .Where(x => !string.IsNullOrWhiteSpace(x))
        .ToList();
var data = result.Where((c,i) => i % 2 == 0).Zip(result.Where((c,i) => i % 2 != 0),
        (delimiter, value) => new KeyValuePair<string, string>(delimiter, value));
foreach (var kvp in data)
    Console.WriteLine("Delimiter: {0}\nValue: {1}", kvp.Key, kvp.Value);

Выход:

Delimiter: &R
Value: Pork && Beans
Delimiter: &C
Value: Document Title
...