Поиск текста и манипулирование - PullRequest
3 голосов
/ 11 августа 2011

Таким образом, файл, который я импортирую в ListBox, выглядит следующим образом (каждый перевод строки является новым элементом в ListBox) :

C2  CAP-00128G 238.385 205.944 0  0402_8   
C1  CAP-00128G 236.260 204.844 0  0402_8   //Same as above 1 (C2)
C18 CAP-00129G 230.960 190.619 0  0402_4   
C19 CAP-00129G 248.060 195.344 0  0402_4
C63 CAP-00129G 231.535 203.844 0  0402_4
C65 CAP-00129G 232.260 195.419 0  0402_4   //Same as above 3 (C18, C19, C63)
C71 CAP-00130G 240.151 195.123 0  0402_4   //1 Occurrence
C4  CAP-00151G 247.435 202.019 90 0402_3   //1 Occurrence
L1  IND-00007G 248.110 205.719 0  0402_4   //1 Occurrence
R30 RES-00455G 273.010 184.644 0  0402_8
R9  RES-00455G 236.260 203.794 0  0402_8
R29 RES-00455G 272.960 174.694 0  0402_8   //Same as above 2 (R30, R9)

Я смотрю на каждый элемент в ListBox и собираю значения 2-й столбец и вижу, сколько раз они встречаются (см. Цифры после текста - то есть 2,4, 1, 1, 1, 3 при просмотре столбцов) и вывод его в файл .txt.Вот как это выглядит (это первая часть файла .txt, вторая часть будет указана ниже).

( 1 0 1 1 0 0 0 0 "" "CAP-00128G" "" 2 0 0 0 0 0 )   // 2 = C2, C1
( 2 0 1 1 0 0 0 0 "" "CAP-00129G" "" 4 0 0 0 0 0 )   // 4 = C18, C19, C63, C65
( 3 0 1 1 0 0 0 0 "" "CAP-00130G" "" 1 0 0 0 0 0 )   // 1 = C71
( 4 0 1 1 0 0 0 0 "" "CAP-00151G" "" 1 0 0 0 0 0 )   // 1 = C4
( 5 0 1 1 0 0 0 0 "" "IND-00007G" "" 1 0 0 0 0 0 )   // 1 = L1
( 6 0 1 1 0 0 0 0 "" "RES-00455G" "" 3 0 0 0 0 0 )   // 3 = R30, R9, R29

Использование этого кода для приведенного выше текста:

List<string> partList = new List<string>();

// Builds original list first.
foreach (var item in placementOneListBox.Items)   //This is getting all the lines in the ListBox and storing them in a List<string>.
{
    // Creates a string of the items in the ListBox. 
    var newItems = item.ToString();

    // Replaces any multiple spaces (tabs) with a single space. 
    newItems = Regex.Replace(newItems, @"\s+", " ");

    // Splits each line by spaces. 
    var eachItem = newItems.Split(' ');

    // Add each item to the List.
    partList.Add(eachItem[1]);
}

Dictionary<string, int> result = new Dictionary<string, int>();
foreach (var item in partList)
{
    if (result.ContainsKey(item))
        result[item]++;
    else
        result.Add(item, 1);
}

foreach (var item in result)
{
    sw.WriteLine("( " + deviceCount + " 0 1 1 0 0 0 0 \"\" \"" + item.Key + "\" \"\" " + item.Value + " 0 0 0 0 0 )");

    deviceCount++;
}

Используя тот же ListBox Я печатаю вторую половину .txt файла.Вторая часть текстового файла выглядит следующим образом:

( 1 1 "DD" 1 238.385 205.944 0 1 2 0 0 "C2" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 2 1 "DD" 1 236.260 204.844 0 1 2 0 0 "C1" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 3 1 "DD" 1 230.960 190.619 0 1 2 0 0 "C18" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 4 1 "DD" 1 248.060 195.344 0 1 2 0 0 "C19" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 5 1 "DD" 1 231.535 203.844 0 1 2 0 0 "C63" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 6 1 "DD" 1 232.260 195.419 0 1 2 0 0 "C65" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 7 1 "DD" 1 240.151 195.123 0 1 2 0 0 "C71" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 8 1 "DD" 1 247.435 202.019 90 1 2 0 0 "C4" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 9 1 "DD" 1 248.110 205.719 0 1 2 0 0 "L1" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 10 1 "DD" 1 273.010 184.644 0 1 2 0 0 "R30" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 11 1 "DD" 1 236.260 203.794 0 1 2 0 0 "R9" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 12 1 "DD" 1 272.960 174.694 0 1 2 0 0 "R29" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )

Использование кода:

foreach (var item in placementOneListBox.Items)
{
    var newItems = item.ToString();
    newItems = Regex.Replace(newItems, @"\s+", " ");

    var eachItem = newItems.Split(' ');

    sw.WriteLine("( " + lineCount + " 0 \"FD\" 1 " + eachItem[2] + " " + eachItem[3]
                      + " 0 0 0 0 0 \"" + eachItem[0] + "\" \"\" \"\" \"\" \"\" 0 0 0 "
                      + lineCount + " 0 0 0 0 0 0 0 \"\" )");
    lineCount++;
}

sw.WriteLine(")");
sw.WriteLine(")");

sw.Close();

ТАК моя проблема:

Вторая часть файлараспечатывается правильно, за исключением того, что мне нужно заменить значение , которое происходит после "DD" во второй части файла, на 1-й (номер) столбец в первой части файла. Итак, вместо из 2-й части распечатанного файла как есть, яхотел бы распечатать его по-разному в зависимости от того, соответствует ли он значениям.Вот как бы мне хотелось, чтобы файл выглядел следующим образом:

( 1 1 "DD" 1 238.385 205.944 0 1 2 0 0 "C2" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 2 1 "DD" 1 236.260 204.844 0 1 2 0 0 "C1" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 3 1 "DD" 2 230.960 190.619 0 1 2 0 0 "C18" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 4 1 "DD" 2 248.060 195.344 0 1 2 0 0 "C19" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 5 1 "DD" 2 231.535 203.844 0 1 2 0 0 "C63" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 6 1 "DD" 2 232.260 195.419 0 1 2 0 0 "C65" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 7 1 "DD" 3 240.151 195.123 0 1 2 0 0 "C71" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 8 1 "DD" 4 247.435 202.019 90 1 2 0 0 "C4" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 9 1 "DD" 5 248.110 205.719 0 1 2 0 0 "L1" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 10 1 "DD" 6 273.010 184.644 0 1 2 0 0 "R30" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 11 1 "DD" 6 236.260 203.794 0 1 2 0 0 "R9" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 12 1 "DD" 6 272.960 174.694 0 1 2 0 0 "R29" "" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
  • Кто-нибудь может мне помочь разобраться с этой проблемой?

РЕДАКТИРОВАТЬ:

Вот ошибка, которую я получаю.

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Проблема может быть решена кратко и относительно легко (или нет) с помощью LINQ:

// Using the input file:
const string str = "C2  CAP-00128G 238.385 205.944 0  0402_8\n"
                    + "C1  CAP-00128G 236.260 204.844 0  0402_8   #Same as above 1 (C2)\n"
                    + "C18 CAP-00129G 230.960 190.619 0  0402_4   \n"
                    + "C19 CAP-00129G 248.060 195.344 0  0402_4\n"
                    + "C63 CAP-00129G 231.535 203.844 0  0402_4\n"
                    + "C65 CAP-00129G 232.260 195.419 0  0402_4   #Same as above 3 (C18, C19, C63)\n"
                    + "C71 CAP-00130G 240.151 195.123 0  0402_4   #1 Occurrence\n"
                    + "C4  CAP-00151G 247.435 202.019 90 0402_3   #1 Occurrence\n"
                    + "L1  IND-00007G 248.110 205.719 0  0402_4   #1 Occurrence\n"
                    + "R30 RES-00455G 273.010 184.644 0  0402_8\n"
                    + "R9  RES-00455G 236.260 203.794 0  0402_8\n"
                    + "R29 RES-00455G 272.960 174.694 0  0402_8   #Same as above 2 (R30, R9)\n";

// And the reader (notice that by using `StringSplitOptions.RemoveEmptyEntries` 
// you don't need your regular expression to normalize spacing):

var listLines = new List<string[]>();
using (var tr = new StringReader(str))
{
    string l;
    while ((l = tr.ReadLine()) != null)
        listLines.Add(l.Split(new[] {' '}, 
            StringSplitOptions.RemoveEmptyEntries));
}

// this is a cool trick when you need to build up a dictionary.  The problem 
// with using a dictionary in a case like this is that, unless you have some
// multidictionary implementation, you are going to be stuck with a lot of 
// extra code that maintains the value collection (you know what I mean... the
// List<string[]> part of Dictionary<string, List<string[]>>.

var lookup = (from line in listLines group line by line[1]).ToArray();

// Part 1 -- The Select allows me to run a lambda function.  In this case, 
// I use a variation that provides me with a counter.  Nothing really special 
// here.

var part1 = lookup.Select(
    (x, i) =>
    string.Format(@"( {0} 0 1 1 0 0 0 0 """" ""{1}"" """" {2} 0 0 0 0 0 )", 
        i + 1, x.Key, x.Count()));

// And Part 2 - A little trickier.  I'm using SelectMany to flatten my dictionary
// back out, but while doing so, I use an anonymous type to effectively decorate
// each line with the index of the group it belongs to.  From then on it is again
// just a standard call to string.Format (which, if you aren't using it, please do.
// It's a lot more readable than string concatenations).

var part2 = lookup.SelectMany((x,i) => x.Select(y => new { Index = i, Item = y }))
    .Select((x,i) => string.Format(
       @"( {0} 1 ""DD"" {1} {2} {3} {4} 1 2 0 0 ""{5}"" """" """" """" 0 0 0 0 0 0 0 0 0 0 0 """" )", 
       i + 1, x.Index + 1, x.Item[2], x.Item[3], x.Item[4], x.Item[0] ));


// And so you can see your results in the console:

Console.WriteLine(string.Join("\n", part1));
Console.WriteLine();
Console.WriteLine(string.Join("\n", part2));

Наконец, вывод:

( 1 0 1 1 0 0 0 0 "" "CAP-00128G" "" 2 0 0 0 0 0 )
( 2 0 1 1 0 0 0 0 "" "CAP-00129G" "" 4 0 0 0 0 0 )
( 3 0 1 1 0 0 0 0 "" "CAP-00130G" "" 1 0 0 0 0 0 )
( 4 0 1 1 0 0 0 0 "" "CAP-00151G" "" 1 0 0 0 0 0 )
( 5 0 1 1 0 0 0 0 "" "IND-00007G" "" 1 0 0 0 0 0 )
( 6 0 1 1 0 0 0 0 "" "RES-00455G" "" 3 0 0 0 0 0 )

( 1 1 "DD" 1 238.385 205.944 0 1 2 0 0 "C2" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 2 1 "DD" 1 236.260 204.844 0 1 2 0 0 "C1" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 3 1 "DD" 2 230.960 190.619 0 1 2 0 0 "C18" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 4 1 "DD" 2 248.060 195.344 0 1 2 0 0 "C19" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 5 1 "DD" 2 231.535 203.844 0 1 2 0 0 "C63" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 6 1 "DD" 2 232.260 195.419 0 1 2 0 0 "C65" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 7 1 "DD" 3 240.151 195.123 0 1 2 0 0 "C71" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 8 1 "DD" 4 247.435 202.019 90 1 2 0 0 "C4" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 9 1 "DD" 5 248.110 205.719 0 1 2 0 0 "L1" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 10 1 "DD" 6 273.010 184.644 0 1 2 0 0 "R30" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 11 1 "DD" 6 236.260 203.794 0 1 2 0 0 "R9" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )
( 12 1 "DD" 6 272.960 174.694 0 1 2 0 0 "R29" "" "" "" 0 0 0 0 0 0 0 0 0 0 0 "" )

То, что я думаю, именно то, что вы ищете.

Итак ... надеюсь, здесь есть кое-что интересное, с чем можно ознакомиться:

  • LINQ (Это может изменить вашу жизнь)
  • Лямбда-функции
  • Анонимные типы
  • SelectMany (с индексатором)
  • String.Format

- ОБНОВЛЕНИЕ -

Если, как уже упоминалось в цитатах, вы получаете элементы из списка, вы можете инициализировать listlines, как показано здесь:

var listLines = from l in ListBox.Items
      select l.ToString().Split(new[] {' '}, 
         StringSplitOptions.RemoveEmptyEntries);

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

0 голосов
/ 11 августа 2011

Это похоже на файл с разделителями.

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

Вы также можете легко пройти по всем строкам таблицы, чтобы выполнить любые необходимые замены.

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

...