2017-02-07 10 views
0

Я ищу, чтобы заменить все вхождение «[2]» в данной строке Вот моя текущая функцияЗаменить экземпляр на основе индекса массива

Dim replace() As String 
replace = Split("3,2,4,1", ",") 
Dim orig As String = "[2] [2] [2] [2]" 
Dim search As String = "[2]" 
sb = New StringBuilder(orig) 
For i As Integer = 0 To replace.Length - 1 

       Dim Occurrence = sb.ToString().IndexOf(search) 
       If Occurrence > -1 Then 
        If (replace(j) = "2") Then 
         sb.Replace(search, "[2]", firstOccurrence, search.Length) 
        j = j + 1 
        Else 
         sb.Replace(search, "[" & replace(j) & "]", firstOccurrence, search.Length) 
         j = j + 1 
        End If 
       End If 

      Next 

На самом деле я получаю это:

Output : [3] [4] [1] [2] 

Я ищу, чтобы получить что-то вроде этого:

Output : [3] [2] [4] [1] 

Спасибо

ответ

0

Поскольку вы заменяете с тем, что у вас уже есть вам нужно следить за начальной точки вашего следующего поиска каждый раз

Dim Occurrence = sb.ToString().IndexOf(search, Occurance) 

И вы уже знаете позицию так

sb.Replace(search, "[2]", Occurrence, search.Length) 

или

sb.Replace(search, "[" & replace(j) & "]", Occurrence, search.Length) 

и заканчиваются

Occurance += search.Length 

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

1

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

Dim orig As String = "[2] [2] [2] [2]" 
    Dim searchText As String = "[2]" 
    Dim replaceChars() As String = Split("3,2,4,1", ",") 
    Dim startIndex As Integer = 0 

    For replaceIndex As Integer = 0 To replaceChars.Count - 1 
     Dim searchIndex As Integer = orig.IndexOf(searchText, startIndex) + 1 
     orig = orig.Remove(searchIndex, 1).Insert(searchIndex, replaceChars(replaceIndex)) 
     startIndex = searchIndex 
    Next 

    MsgBox(orig) 

Примечания переменной StartIndex, она используется, чтобы сказать IndexOf, где начать поиск ... и в конце каждого цикла, он обновляется до последней позиции где был найден матч.Это позволяет IndexOf от поиска всей строки во время следующей итерации

+0

Проблема с этим решением, хотя это получает быть большими борами памяти в большем сценарии данных. Все, что смена строки плохо обрабатывается VB –

+0

Согласен, она также не учитывает, если было более 4 вхождений «[2]», поэтому было бы неважно просто копировать/вставлять и используйте ... так что OP используйте это как пример того, как можно использовать startIndex, но есть и другие проблемы, которые необходимо продумать, а также – soohoonigan

+0

спасибо за вашу помощь, на самом деле у меня есть 80 файлов (ответы) и 80 файлов (вопросы) с большими данными .. Я буду использовать что-то вроде этого orig = File.ReadAllText ("F: \\" & filname & ".csv"), replace = Split (File.ReadAllText ("F:" & filname & «.txt»), и я закончу что-то вроде этого File.WriteAllText («F: \» & filname & «.csv», sb.ToString), я думаю, что буду использовать большую память – Dexter

-1

Одна вещь, которую вы можете сделать, чтобы сделать это быстро расщепляется вашу строку на подстроки, которую вы пытаетесь заменить, так что эта строка:

one[2]two[2]three[2]four[2]five 

становится массивом с пятью элементами:

{"one", "two", "three", "four", "five"} 

После того, как вы есть, что вы можете «молния» он вместе с заменами:

{"one", "two", "three", "four", "five"} 
& {"[3]", "[2]", "[4]",  "[1]"} 
----------------------------------------- 
    {"one[3]", "two[2]", "three[4]", "four[1]", "five"} 

и присоединиться все это вместе:

one[3]two[2]three[4]four[1]five 

В коде, который выглядит следующим образом:

Dim replace As String() = {"[3]", "[2]", "[4]", "[1]"} 
Dim orig = "[2] [2] [2] [2]" 
Dim search = "[2]" 

Dim result = String.Concat(
    orig.Split({search}, StringSplitOptions.None).Zip(
     Enumerable.Concat(replace, {""}), 
     Function (a, b) a & b 
    ) 
) 

Это, вероятно, хорошая идея, чтобы разделить это на другую функцию, также:

<Extension> 
Function ReplaceSequence(s As String, find As String, replacements As IEnumerable(Of String)) As String 
    Return String.Concat(
     s.Split({find}, StringSplitOptions.None).Zip(
      Enumerable.Concat(replacements, {""}), 
      Function (a, b) a & b 
     ) 
    ) 
End Function 

, который затем может использоваться следующим образом:

Dim result = "[2] [2] [2] [2]".ReplaceSequence(
    "[2]", 
    {"[3]", "[2]", "[4]", "[1]"} 
) 
+0

Интересное решение. данные обманывают LOL –

+0

@Trevor: Я хотел облегчить его в функцию многократного использования, но оттуда это нормально для '" 3,2,4,1 ".Split ({", "c}). Выберите (Fu nction (n) "[" & n & "]") '. – Ryan

+0

Я начал играть с разбиением его на массив, но пример слишком простой, и он быстро усложняется для разных длин значений и оригиналов. Лучшим решением может быть просто выполнить быструю замену оригинала, чтобы изменить его с [2] на что-то еще, чтобы он не возвращал то, что он извлек. Отвечать на исходный вопрос я имею в виду. –

0

дешев и грязный раствор

Dim Values() As String = {"3", "2", "4", "1"} 
    Dim Orig As String = "[2] [2] [2] [2]" 
    Dim Output As String = Replace(Orig, "[2]", "[^]") 
    For Each ReplaceMent As String In Values 
     Output = Replace(Output, "[^]", "[" & ReplaceMent & "]", 1, 1) 
    Next 
    'Put back any unused twos 
    Output = Replace(Output, "[^]", "[2]") 
+0

Ваш второй ответ более ясен, используя Occurrence + = replace.Length, спасибо – Dexter

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

  • Нет связанных вопросов^_^