Regex для извлечения части имени файла - PullRequest
0 голосов
/ 30 мая 2010

У меня есть текстовые файлы, отформатированные так:

R156484COMP_004A7001_20100104_065119.txt

Мне нужно последовательно извлекать R ****** COMP, номер 004A7001, 20100104 (дата), и мне не важно число 065119. проблема в том, что не ВСЕ анализируемые файлы имеют точное соглашение об именах. некоторые могут быть такими:

R168166CRIT_156B2075_SU2_20091223_123456.txt

или

R285476COMP_SU1_125A6025_20100407_123456.txt

Итак, как я могу использовать regex вместо разделения, чтобы всегда получать этот серийный номер (например, 004A7001), дату (например, 20100104) и R ****** COMP (или CRIT) ???

Вот что я делаю сейчас, но он только форматирует файлы, как в моем первом примере.

if (file.Count(c => c == '_') != 3) continue;

и далее в коде у меня есть:

string RNumber = Path.GetFileNameWithoutExtension(file);

string RNumberE = RNumber.Split('_')[0];

string RNumberD = RNumber.Split('_')[1];

string RNumberDate = RNumber.Split('_')[2];

DateTime dateTime = DateTime.ParseExact(RNumberDate, "yyyyMMdd", Thread.CurrentThread.CurrentCulture);
string cmmDate = dateTime.ToString("dd-MMM-yyyy");

ОБНОВЛЕНИЕ: Это то, где я сейчас нахожусь, - я получаю ошибку, чтобы проанализировать RNumberDate для фактического формата даты. "Невозможно неявно преобразовать тип 'RegularExpressions.Match' в 'строку'

 string RNumber = Path.GetFileNameWithoutExtension(file);

 Match RNumberE = Regex.Match(RNumber, @"^(R|L)\d{6}(COMP|CRIT|TEST|SU[1-9])(?=_)", RegexOptions.IgnoreCase);

 Match RNumberD = Regex.Match(RNumber, @"(?<=_)\d{3}[A-Z]\d{4}(?=_)", RegexOptions.IgnoreCase);
 Match RNumberDate = Regex.Match(RNumber, @"(?<=_)\d{8}(?=_)", RegexOptions.IgnoreCase);



DateTime dateTime = DateTime.ParseExact(RNumberDate, "yyyyMMdd", Thread.CurrentThread.CurrentCulture);
string cmmDate = dateTime.ToString("dd-MMM-yyyy")

Ответы [ 3 ]

3 голосов
/ 30 мая 2010

Вы можете использовать возможности нескольких регулярных выражений для решения этой проблемы.

compNumber:   /^R\d{6}(COMP|CRIT)(?=_)/
date:         /(?<=_)\d{8}(?=_)/
serialNumber: /(?<=_)\d{3}[A-Z]\d{4}(?=_)/

part:         /(?<=_).*?(?=_)/

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

1 голос
/ 30 мая 2010
string filename = "R285476COMP_SU1_125A6025_20100407_123456.txt";

Match m = Regex.Match(filename,
    @"^(R\d+(?:COMP|CRIT))_(?:SU\d+_)?(\d+[A-Z]+\d+)_(?:SU\d+_)?(\d{8})_.*$",
    RegexOptions.IgnoreCase);

if (m.Success)
{
    Console.WriteLine(m.Groups[1].Value);    // R285476COMP
    Console.WriteLine(m.Groups[2].Value);    // 125A6025
    Console.WriteLine(m.Groups[3].Value);    // 20100407
}
1 голос
/ 30 мая 2010

Я не совсем понимаю правила анализа вашей строки, но совет, который может помочь:

Посмотрите на RegEx.Split и RegEx.Matches чтобы разбить вашу строку с помощью RegEx.

Создайте свой RegEx, я предлагаю превосходный строитель / проверка RegEx / учебное пособие .С помощью этого инструмента вы можете ввести кучу строк в большую текстовую область (например, ваши серийные номера или что бы то ни было) и в интерактивном режиме ввести свой RegEx, чтобы увидеть, какие части в настоящее время соответствуют.Справа на странице есть «учебное пособие», которое поможет вам научиться строить RegEx.

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