What I thought would be simple is kickin' my tail...

What I’m trying to do is replace string between two references with something else… for example:

dim myString as string
myString = “[!]hello[!] there… how are [!]you[!] doing today?”

Anything between two [!] I am trying to pull out and replace with something else, while leaving everything else intact. I’ve been trying to tinker with inStr, but it’s killin’ me here. Anybody know if an easier solution at this? Could RegEx be a potential candidate? There could be anything between the reference points, and it can contain any amount of words, and start anywhere… not just at the beginning of the string, and finish at the end. Some strings don’t have any, some can contain 7 or 8 references to pull and replace. Again, this is kicking my tail… any help would be appreciated.

You could try splitting the string based on the [!], loop over the array of strings and the join back with the new strings… Or use NthField and replace right in the string…

You can do:
myString=myString.replace("[!]hello[!]",“goodbye”).replace("[!]you[!]",“me”)
It’s not always the safest approach however

Here is an implementation of Shao’s idea…

Function ReplaceAllBetween(sourceString As String, tag As String, replacementString As String) As String
  Dim result() As String
  Dim i As Integer
  
  result = Split(sourceString, tag)
  
  if Left(sourceString, Len(tag)) = tag then
    result.Remove(0)
    i = 0
  else
    i = 1
  end if
  
  while i <= result.Ubound
    result(i) = replacementString
    i = i + 2
  wend
  
  return Join(result, "")
  
End Function

This method can then be used as…

  dim myString as string
  myString = "[!]hello[!] there... how are [!]you[!] doing today?"
  
  MsgBox ReplaceAllBetween(myString, "[!]", "ABC")

There is probably a way to do this with regular expressions which will be a more elegant solution.

As always… you guys delivered, and quickly! Appreciate the replies… and I’ll miss with the split suggestion. That didn’t even occur to me to try. Thanks!

I believe Kem Tekinay posted a RegEx on Xippets to do exactly?
I could be wrong though, so why not take a look - it could save you a headache :slight_smile:

Hope that helped.

This is exactly the kind of problem regular expressions are meant to solve. The RegEx way is this:

dim rx as new RegEx
rx.SearchPattern = "(\\[!\\]).*(\\[!\\])"
rx.ReplacementPattern = "$1ABC$2"

rx.Options.ReplaceAllMatches = True
rx.Options.Greedy = False
rx.Options.DotMatchAll = True

dim replacedText as string = rx.Replace( sourceText )

If you have my M_String module, you could simply do:

replacedText = sourceText.ReplaceRegEx_MTC( "(?Us)(\\[!\\]).*(\\[!\\])", "$1ABC$2" )

(The “(?Us)” bit sets the options within the pattern.)

I like Alwyn’s code as a generalized approach, but with very large text, a regular expression (especially using the MBS plugins) should be faster.

You don’t need to check the first tag or remove it, especially since that would slow it down. If the string starts with the tag, result(0) will be empty anyway, so the code can be simplified a bit.

Function ReplaceAllBetween(sourceString As String, tag As String, replacementString As String) As String
  Dim result() As String
  Dim i As Integer
  
  result = Split(sourceString, tag)
  for i = 1 to result.Ubound step 2
    result( i ) = replacementString
  next i  
  return Join(result, "")
End Function

BTW, the difference in the two approaches is that Alwyn’s code will remove the tags whereas the RegEx-based code I provided will preserve them. Eric, I’m not sure which you wanted, so just be aware. Either approach can be easily modified to do the other.

Ah yes, I forgot to remove that check… it was an artifact from my first attempt at the algoritm where I called the

Return Join(result, "")

mistakenly as

Return Join(result)

(which defaults to Join(result, " "), and used the check as a workaround.

Meant to remove it before posting but it slipped my mind.