|
-
Aug 7th, 2011, 05:48 AM
#1
Thread Starter
New Member
Replace two duplicate word into two different words
Hi members, Can some one solve my code.
I need to Replace two duplicate word into two different words.
Like:
abc is a search engine and also abc a search engine.
to
google is a search engine and also yahoo a search engine.
I tried this.
TextBox1.Text = Replace(TextBox1.Text, "abc", "google")
But it replaces all abc to google. But I need to change first abc to google and second abc to yahoo and so on.
also tried this one
Dim m14 As MatchCollection = Regex.Matches(TextBox1.Text, "abc", RegexOptions.Singleline + RegexOptions.IgnoreCase)
For Each n1 As Match In m14
Dim value As String = n1.Groups(0).Value
'MsgBox(value)
If value.Contains("abc") Then
TextBox1.Text = Replace(TextBox1.Text, "abc", "google")
'MsgBox("found")
End If
Next
I Need some ones help.
-
Aug 7th, 2011, 11:01 AM
#2
Re: Replace two duplicate word into two different words
The regex solution is intuitive but gets ugly fast. You can look at the index of each match to see where it was, but once you make one replacement all future indices are invalid. But that's only true going forward. If you go backwards, you can rely on the indices. But then you have to deal with the case where there are more or less "abc" instances than words. Turns out that's not tough to deal with.
First I built some test cases. Let's say we want to replace in this order: "Google", "Yahoo", "DuckDuckGo". We need a string with 2, 3, and 4 "abc" instances to test out all of our cases. Here's my tests:
- "You got your abc in my abc."
- "I went to the dance and saw abc, abc, and abc."
- "I don't like abc, but it's not as bad as abc. Don't abc my abc."
Here's the algorithm I dreamed up:
Code:
* Find all matches for "abc" in the string.
* If there are more matches than replacements, remove the last matches.
* If there are more replacements than matches, ignore the last replacements.
* Starting at the last match and replacement:
* Get the index of the match.
* Remove "abc" from that index.
* Insert the current replacement at the index.
* Move to the previous match and previous replacement.
Here's the implementation:
Code:
' Import System.Text.RegularExpressions
Function ReplaceInSequence(ByVal input As String, ByVal target As String, ByVal replacements() As String) As String
Dim pattern = String.Format("\b{0}\b", target)
Dim patternMatches = Regex.Matches(input, pattern)
' Life's easier later if we get the matches out of MatchCollection and into an array.
Dim matches(patternMatches.Count - 1) As Match
patternMatches.CopyTo(matches, 0)
' If there are more targets than replacements, take only the first ones
If matches.Count > replacements.Length Then
matches = matches.Take(replacements.Length).ToArray()
End If
' If there are more replacements than matches, we ignore them by starting at the same
' index in replacements as the last index of matches.
Dim output As String = input
For matchIndex = matches.Length - 1 To 0 Step -1
Dim targetIndex As Integer = matches(matchIndex).Index
' Remove the target from the string
output = output.Remove(targetIndex, target.Length)
' Insert the replacement
output = output.Insert(targetIndex, replacements(matchIndex))
Next
Return output
End Function
Here's an example of how to use it (also how I tested):
Code:
Dim testStrings() = {"You got your abc in my abc.",
"I went to the dance and saw abc, abc, and abc.",
"I don't like abc, but it's not as bad as abc. Don't abc my abc."}
Dim replacements() = {"Google", "Yahoo", "DuckDuckGo"}
For Each value In testStrings
Dim replaced = ReplaceInSequence(value, "abc", replacements)
Console.WriteLine(replaced)
Next
There's a more memory-efficient way to do this with a StringBuilder, but it's a bit more complicated and I won't discuss it unless you come back with complaints you're getting OutOfMemoryException.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|