2009-11-18 2 views
1

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

Программа Я пытаюсь реализовать будет делать следующее:

Он попросит пользователя ввести каталог. Он будет искать в каталоге текстовые файлы. Он будет перебирать текстовые файлы, анализировать их и сохранять в одной таблице. Текстовые файлы имеют следующую структуру:

(это текстовый файл 1)

001 - Milan (Citizens) 

Pitch Street 

    John Doe    15, F1 2    35022I   
    Janette Doe   17, F7 2    32345I    

Angel Street 

    Mark Skate    12, F3 2    35532I   
    Jacqueline Skate  18, F6 2    54343I     

(это текстовый файл 2)

002 - Rome (Citizens) 

Colosseum Street 

    Christian Troy   21, F8 5    21354I   
    Janette Doe   17, F7 2    23453T    

Pope Street 

    Sean McNamara   Villa McNamara  12424I   
    Julia McNamara   Villa McNamara  43344I      

и т.д ...

001 - Милан и т. Д. - это город. Это находится один раз в начале каждого текстового файла. Colosseum Street и т. Д. - это название улицы. Затем для каждой улицы есть список с тремя столбцами: имя, адрес, идентификационная карточка.

Что мне нужно - это вставить каждого гражданина в базу данных. база данных будет иметь одну таблицу в следующем формате:

имя, фамилия, адрес id_card, город, улица

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

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

Большое спасибо заранее!

С уважением, Крис

ответ

9

Попробуйте разбить задачу на более мелкие проблемы

  • написать тестовое приложение, которое будет получить каталог от пользователя How to browse for folder

  • написать тестовое приложение, которое будет перебрать все файлы в каталоге Exclude certain file extensions when getting files from a directory

  • написать тестовое приложение, которое будет читать файл по одной строке за один раз https://stackoverflow.com/search?q=c%23+read+lines+in+file

  • написать тестовое приложение, которое будет анализировать данный текст

    Для этого я хотел бы создать государство, основанное парсер. Он знает, что он ищет дальше, и не переходит в следующее состояние, если не нашел его, - посмотрите на государственные машины для идеи. Это будет работать, если формат файла также определен, как показывают ваши примеры.

+1

+1 для здравого смысла. – Kev

+0

Спасибо за ссылки на учебники. В настоящее время мне удалось разобрать текстовый файл с тысячами строк, и он выглядит хорошо. – seedg

0

Вы застряли с этим форматом файла? (Безусловно, это ужасно!) В настоящий момент нет четкого способа анализа парсером улицы или человека. Если вы создаете эту файловую структуру с нуля, было бы лучше сделать это в XML или даже CSV.

+0

голосование +1 для перехода на XML – Simon

+2

Выглядит довольно структурировано для меня. – Kev

+1

У улиц нет прокладки, тогда как люди делают. – Kris

1

У вас есть два варианта:

  1. чтения одной строки во время; первая строка будет вашей городской информацией, следующая строка, начинающаяся с столбца 0 (без начальных пробелов), будет вашим адресом, а строки, начинающиеся с двух пробелов, будут представлять вашу информацию гражданина
  2. Вы можете создать регулярное выражение, соответствующее этому формату файла, и полностью совпадают со всем файлом
+0

или * линии, начинающиеся с 3 цифр * являются информацией города, строки, начинающиеся с буквы *, - это название улицы, строки, начинающиеся с * пробелов *, являются информацией гражданина. Вы можете делать это с помощью регулярных выражений. – pavium

+0

@pavium, ty для ваших комментариев; Я пытаюсь создать уникальное регулярное выражение для этого; вы можете помочь? –

0

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

  1. Каждая строка в адресе лица имеет имя, строение/плоский и карточный идентификатор в фиксированных положениях.
  2. Имя человека является Имя и фамилия (хотя может справиться с любым количеством средних имен/инициалами)
  3. Город ID и имя на первой строке
  4. Человек строка всегда начинается с, по меньшей мере, два пространства
  5. пустые строки только что, пустой

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

Я уверен, что есть много оптимизаций, но это там, чтобы ты:

using System; 
using System.IO; 

namespace AddressParser 
{ 
    class Program 
    { 
    public class TownInfo 
    { 
     public int TownID { get; set; } 
     public string TownIDAsString { get; set; } 
     public string Town { get; set; } 
    } 

    public class Citizen 
    { 
     public TownInfo Town { get; set; } 
     public string Street { get; set; } 
     public string FirstName { get; set; } 
     public string Surname { get; set; } 
     public string Building { get; set; } 
     public string Flat { get; set; } 
     public string CardID { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     string dataFile = @"d:\testdata\TextFile1.txt"; 

     ParseAddressFileToDatabase(dataFile); 
    } 

    static void ParseAddressFileToDatabase(string dataFile) 
    { 
     using(StreamReader sr = new StreamReader(dataFile)) 
     { 
     string line; 
     bool isFirstLine = true; 

     string currentStreet = null; 
     TownInfo townInfo = null; 

     while((line = sr.ReadLine()) != null) 
     { 
      if(isFirstLine) 
      { 
      townInfo = ParseTown(line); 
      isFirstLine = false; 
      } 

      if(line.Trim() == String.Empty) 
      continue; 

      while(line != null && line.StartsWith(" ")) 
      { 
      Citizen citizen = ParseCitizen(line, townInfo, currentStreet); 

      // 
      // Insert record into DB here 
      // 

      line = sr.ReadLine(); 
      } 

      currentStreet = line; 
     } 
     } 
    } 

    private static TownInfo ParseTown(string line) 
    { 
     string[] town = line.Split('-'); 
     return new TownInfo() 
     { 
     TownID = Int32.Parse(town[0].Trim()), 
     TownIDAsString = town[0].Trim(), 
     Town = town[1].Replace("(Citizens)","").Trim() 
     }; 
    } 

    private static Citizen ParseCitizen(string line, TownInfo townInfo, string currentStreet) 
    { 
     string[] name = line.Substring(2, 23).Trim().Split(' '); 

     string firstName = name[0]; 
     string surname = name[name.Length - 1]; 

     // Assumes fixed positions for some fields 
     string buildingOrFlat = line.Substring(24, 22).Trim(); 
     string cardID = line.Substring(46).Trim(); 

     // Split building or flat 
     string[] flat = buildingOrFlat.Split(','); 

     return new Citizen() 
     { 
     Town = townInfo, 
     Street = currentStreet, 
     FirstName = firstName, 
     Surname = surname, 
     Building = flat.Length == 0 ? buildingOrFlat : flat[0], 
     Flat = flat.Length == 2 ? flat[1].Trim() : "", 
     CardID = cardID 
     }; 
    } 
    } 
} 
1

Было бы хорошо, если ОП может изменить формат, но не указано, как возможность.

Я думаю, что один подход к ...

  1. Генерировать много примеров текстового файла, которые охватывают все возможные сценарии.
  2. Используйте это как руководство для составления регулярных выражений для структуры текста (или его частей).
  3. Запишите код анализа, который принимает в качестве входного текста текст, который совпадают с выражениями - по одному для каждого созданного регулярного выражения.
  4. Наполните анализируемый материал любой структурой данных.

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

0

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

Вы не должны хранить свой адрес против своего гражданина - в будущем вы приступите к сборщику. Вместо этого, имеют отдельную таблицу:

Citizen: ID, Имя, Фамилия, IDcard

Адрес: ID, адрес, город, улица

CitizenAddress: CitizenID, AddressID

So у вас есть одна таблица с данными о имени и идентификационной карте гражданина, а другая - с адресами - тогда адрес связан с гражданином, используя таблицу «CitizenAddress».

Какая выгода от этого дает вам?

Ну, если у вас есть два гражданина по одному адресу, вам нужно только один раз сохранить адрес. Кроме того, если у вас есть сценарий, когда гражданин может быть указан по двум адресам, то это же относится. Вы можете расширить эту структуру, чтобы поддерживать историю проживания гражданина в определенный момент времени - поскольку вам не нужно переписывать адрес при его перемещении.

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