Метарегулярные выражения? - PullRequest
0 голосов
/ 24 августа 2011

Некоторое время назад я написал утилиту маршрутизации файлов (.NET), чтобы проверить расположение и шаблон имени файла и переместить его в другое предварительно сконфигурированное место на основе совпадения. Довольно простые, понятные вещи. Я включил возможность незначительных преобразований с помощью ряда действий поиска и замены регулярных выражений, которые можно назначить файлу «route», с целью добавления строк заголовка, замены запятых на каналы, и тому подобное.

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

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

Если мне нужно написать другой преобразователь, есть ли предложения о том, как сделать его достаточно универсальным, чтобы его можно было использовать повторно? Я подумываю добавить опцию XSLT-трансформера, но мое понимание XSLT не так велико.

Меня попросили привести пример. Скажем, у меня есть файл, подобный так:

FILE001DETAILCOUNT002
BATCH01
DETAIL001FOO
BATCH02
DETAIL001BAR

этот файл будет разделен и сохранен в двух местах. Файлы будут выглядеть так:

FILE001DETAILCOUNT001
BATCH01
DETAIL001FOO

и

FILE001DETAILCOUNT001
BATCH01
DETAIL001BAR

так что наклейка для меня - это значение DETAILCOUNT заголовка файла.

Ответы [ 2 ]

1 голос
/ 02 сентября 2011

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

Регулярное выражение может захватывать только текст, который существует где-то в исходном материале, оно не может генерировать новый текст. Так что если вы не можете найти нужное вам число в какой-то момент в источнике, вам не повезло. К сожалению.

1 голос
/ 25 августа 2011

Моя программа сначала разбивает текст на пакеты.

Я думаю, вы согласитесь, что повторное упорядочение номера детали - самая сложная часть.Вы можете сделать это с делегатом MatchEvaluator.

Regex.Replace (
   text, // the text replace part of
   @"(?<=^DETAIL)\d+", // the regex pattern to find.
   m => (detailNum++).ToString ("000"), // replacement (evaluated for each match)
   RegexOptions.Multiline);

Посмотрите, как предыдущий код увеличивается detailNum в начале каждой партии.

  var contents = 
@"FILE001DETAILCOUNT002
BATCH01
DETAIL001FOO
BATCH02
DETAIL001BAR";

  // foreach batch....
  foreach (Match match in Regex.Matches (contents, @"BATCH\d+\s+(?:(?!BATCH\d+).*\s*)+"))
  {
     Console.WriteLine ("==============\r\nFile\r\n================");
     int batchNum = 1;
     int detailNum = 1;
     StringBuilder temp = new StringBuilder ();
     TextWriter file = new StringWriter (temp);
     // Your file here instead of my stringBuilder/StringWriter

     string batchText = match.Value;
     int count = Regex.Matches (batchText, @"^DETAIL\d+", RegexOptions.Multiline).Count;
     file.WriteLine ("FILE001DETAILCOUNT{0:000}", count);
     string newText = Regex.Replace (batchText, @"(?<=^BATCH)\d+", batchNum.ToString ("000"), RegexOptions.Multiline);
     newText = Regex.Replace (
        newText, 
        @"(?<=^DETAIL)\d+", 
        m => (detailNum++).ToString ("000"), // replacement (evaluated for each match)
        RegexOptions.Multiline);
     file.Write (newText);

     Console.WriteLine (temp.ToString ());
  }

печатает

==============
File
================
FILE001DETAILCOUNT001
BATCH001
DETAIL001FOO

==============
File
================
FILE001DETAILCOUNT001
BATCH001
DETAIL001BAR
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...