У меня есть большой текстовый файл, который я пытаюсь разобрать. Чтобы проанализировать этот файл, мне нужно удалить ВСЕ вкладки перед строкой, но не после.

Так например ...

string sample = "\t\t\tThis is a string \t with a tab";
sample = RemoveInitialTabs(sample);
// sample should now be "This is a string \t with a tab";

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

for (int i = file_content.Count - 1; i > -1; i--)
{
   // Remove initial tabs...
   int size = 0;
   for (int j = 0; j < file_content[i].Length; j++)
   {
      if (file_content[i][j] != '\t')
      {
         break;
      }
      else
      {
         size = j + 1;
      }
   }

   if (size > 0)
   {
      file_content[i] = file_content[i].Remove(0, size);
   }
}

Это работает, но очень медленно (из-за размера содержимого файла, запуск обычно занимает около 66 453 мсек ТОЛЬКО для удаления вкладок) ....

Есть идеи?

2
Ricky 25 Ноя 2016 в 23:36

3 ответа

Лучший ответ

Думаю, вам может помочь TrimStart(params char[] trimChars) Ссылка MSDN

Например, вы можете использовать это:

sample = sample.TrimStart(new char[] {'\t'});

Результат этого будет таким, как хотелось бы.

2
Bojan B 25 Ноя 2016 в 20:43

Попробуйте с регулярным выражением:

string pattern = "^\s*";
for (int i = file_content.Count - 1; i > -1; i--)
{   
    file_content[i] = Regex.Replace(file_content[i], pattern, String.Empty));
}
0
MarkusEgle 25 Ноя 2016 в 20:49

Единственное место, которое, я думаю, вы могли бы сэкономить (совсем немного): зачем сначала читать все строки, а затем обрабатывать их и иметь дело со всем копированием двух огромных массивов ?!

Что я имею в виду: почему бы вам не удалить ведущие вкладки прямо при чтении текстовых файлов?

С другой стороны; Ваше текущее решение поддерживает принцип «разделения ответственности». И это открывает дверь для одного потенциального улучшения в отношении общего времени выполнения: после прочтения исходного содержимого вы можете просто разрезать этот массив и использовать несколько потоков для обрезки различных частей этого массива в параллельном .

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

2
GhostCat 25 Ноя 2016 в 20:44