Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 8 
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Member
Статус: Не в сети
Регистрация: 22.04.2007
Люди, подскажите если знаете ответ.
Задача в следующем:
К примеру есть строка "word, 1word, wordy, word"
мне необходимо заменить слово ''word' в этой строке на new,
должно плучиться "new, 1word, wordy, new"
Поясню, слово которое заменится не должно быть частью другого слова.
пока разбираюсь с Regex, но то что требуется пока не получается.
желательно на С# если можно :roll:



Партнер
 

Advanced member
Статус: Не в сети
Регистрация: 16.11.2006
Откуда: Всегда!
Вот возможный подход

Код:
    class Program
    {
        static void Main()
        {
            String line = "One,two,one,Two,oneTwo,Onetwo,onetwo,OneTwo";
            String target_to_replace = "one";
            String new_substring = "Three";
           
            Console.WriteLine(line);
            Console.WriteLine (SubstringReplacement(line,target_to_replace,new_substring));
        }

        static String SubstringReplacement(String source, String target, String substitute)
        {
            Char separator = ',';
            String[] substrings = source.Split(separator);
            StringBuilder sb = new StringBuilder();
            foreach (String s in substrings)
            {
               sb.Append(s == target ? substitute : s);
               sb.Append(separator);
            }
            sb.Remove(sb.Length-1, 1);
            sb.Append("\n");
            return sb.ToString();
        }
    }


Для реальных строк надо создать массив разделителей char[] и собирать в строку StringBuilder, идя по исходной, с подстановкой соответствующих сепараторов.

PS. Кто постит одно и то же в разных местах, получает подарки от модератора.


 

Member
Статус: Не в сети
Регистрация: 05.12.2005
zauropod
Стиль программы имхо можно улучшить, использование "\n" вобще в C# не рекомендуется впринципе.
Мой подход чуть более доработанный, описал я его здесь:
http://forums.overclockers.ru/viewtopic ... 50#5544050

Но раз мы дошли до кода, то приведу и его:

Код:
using System;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string sourceString = "word,1word,wordy,word";
      string oldWord = "word";
      string newWord = "new";
      string separator = ",";

      string[] words = sourceString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
      for (int i = 0; i < words.Length; i++) if (words[i] == oldWord) words[i] = newWord;

      string targetString = string.Join(separator, words);
      Console.WriteLine(targetString);
      Console.ReadKey();
    }
  }
}


Или же с использованием Linq:
Код:
using System;
using System.Linq;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string sourceString = "word,1word,wordy,word";
      string oldWord = "word";
      string newWord = "new";
      string separator = ",";

      string targetString = string.Join(separator,
        (from s in sourceString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries)
         select (s == oldWord ? newWord : s)).ToArray());
      Console.WriteLine(targetString);
      Console.ReadKey();
    }
  }
}


 

Advanced member
Статус: Не в сети
Регистрация: 16.11.2006
Откуда: Всегда!
sashar2 писал(а):
Стиль программы имхо можно улучшить

Нет предела совершенству :)
sashar2 писал(а):
использование "\n" вобще в C# не рекомендуется впринципе

В данном случае - безусловно. Но если текст большой, сепараторов много, текст, пробелы и прочие сепараторы нужно оставить как было, то однозначно надо тспользовать класс StringBuilder - код будет быстрее в ТЫСЯЧИ раз обычных операций со строками, конкатенациями и пр., что на больших текстах сразу будет заметно. На версиях Net 3.x, правда, я не тестировал. А собирая весь текст в одну строку типа StringBuilder, никак не обойтись без проклятого "\n", или utf варианта, как бы кто не рекомендовал :).


 

Member
Статус: Не в сети
Регистрация: 05.12.2005
zauropod
А по какой причине нельзя использовать Environment.NewLine ?

Насчет скорости в данной ситуации см. тест:

Код:
using System;
using System.Linq;
using System.Diagnostics;
using System.Text;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string sourceString = "word,1word,wordy,word";
      string oldWord = "word";
      string newWord = "new";
      string separator = ",";

      //prepare long string
      for (int i = 0 ; i < 20; i++)
        sourceString += "," + sourceString;
      //sourceString.Length = 23 068 671
      //

      Stopwatch clock = new Stopwatch();
      while (true)
      {
        clock.Start();
        SubstringReplacement(sourceString, oldWord, newWord);
        Console.WriteLine("SubstringReplacement 1 : {0}", clock.Elapsed);
        //00:00:01.4604643
        clock.Reset();

        clock.Start();
        Test1(sourceString, oldWord, newWord, separator);
        Console.WriteLine("Test 1                 : {0}", clock.Elapsed);
        //00:00:01.4106825
        clock.Reset();

        clock.Start();
        Test2(sourceString, oldWord, newWord, separator);
        Console.WriteLine("Test 2                 : {0}", clock.Elapsed);
        //00:00:01.5230621
        clock.Reset();

        Console.WriteLine();
      }
    }

    static string Test1(string sourceString, string oldWord, string newWord, string separator)
    {
      string[] words = sourceString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
      for (int i = 0; i < words.Length; i++) if (words[i] == oldWord) words[i] = newWord;

      string targetString = string.Join(separator, words);
      return targetString;
    }

    static string Test2(string sourceString, string oldWord, string newWord, string separator)
    {
      string targetString = string.Join(separator,
        (from s in sourceString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries)
         select (s == oldWord ? newWord : s)).ToArray());
      return targetString;
    }

    static String SubstringReplacement(String source, String target, String substitute)
    {
      Char separator = ',';
      String[] substrings = source.Split(separator);
      StringBuilder sb = new StringBuilder();
      foreach (String s in substrings)
      {
        sb.Append(s == target ? substitute : s);
        sb.Append(separator);
      }
      sb.Remove(sb.Length - 1, 1);
      sb.Append("\n");
      return sb.ToString();
    }
  }
}


P.S> Результаты записывались после десятого прогона, но стоит заметить, что соотношение чисел от прогона к прогону не менялось.


 

Advanced member
Статус: Не в сети
Регистрация: 16.11.2006
Откуда: Всегда!
sashar2 писал(а):
А по какой причине нельзя использовать Environment.NewLine ?

Я говорил о вполне конкретных задачах, например, пару лет назад писал редактор с подсветкой синтаксиса. Естественно, используется rtf по его спецификации. Дальше надо объяснять? :)

Традиционно подобные редакторы перелопачивают все лексемы, и хотя трудно представить многомегабайтные файлы-исходники (не суммарно, а отдельным модулем), тем не менее, для очень больших кусков будет чувствоваться задержка. А на C# без использования класса StringBuilder это вообще, для больших текстов, нереально.
Мой редактор делал поиск только для того куска, который виден в окне просмотра (реально, конечно, просматривался и весь текст в поисках, к примеру, открытых символов комментирования, чтобы правильно отобразить в этом случае).

sashar2 писал(а):
Насчет скорости в данной ситуации см. тест

Не совсем корректные тесты.
Я бы сослался, к примеру, на статью http://www.chinhdo.com/20070929/stringbuilder-part-2/ , там для конкатенации небольшое исследование, в том чисте и для инетчиков будет интересно про литералы.


 

Member
Статус: Не в сети
Регистрация: 05.12.2005
zauropod
Соглашусь с вами, что говорим о разных областях :) Я лишь хотел показать, что StringBuilder в конкретной задаче не является чем-то, что обеспечивает большой перевес во времени.

P.S>
По моему мы разошлись, настало время остановиться. Исходного кода для товарища -=Barmalei=- должно хватить ;)


 

Member
Статус: Не в сети
Регистрация: 22.04.2007
О! Спасибо большое! Постараюсь больше не размножать свои посты!


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 8 
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan