I’m using an array to check if any values are contained in a string. The way I’m approaching it is first replacing any matched values with a word like, “bad”, and then I’m not showing any strings that contain the word “bad”. I’ll be using this code with a ListBox, but in the example below, I’m just printing to a TextArea. If there’s a better way to approach this, I’m definitely open to ideas.
Here is some working code. The example below returns “She had bad coins”:
dim TextArray as string = array("one","two","three")
foo = "She had two coins"
for each t in TextArray
foo = replaceall(foo , t, "bad" )
TextArea.text = foo
next
However, when I add an if statement to check if the word “bad” is included in the string, this code returns “She had two coins”
dim TextArray as string = array("one","two","three")
foo = "She had two coins"
for each t in TextArray
foo = replaceall(foo , t, "bad" )
if InStr(foo, "bad") = 0 then
TextArea.text = foo
end if
next
What is causing foo to revert back to the pre-replaceall value?
That change is giving me, “She had bad coins”, which is a step in the right direction.
I was attempting to use “= 0” to avoid printing foo if it contained the word “bad”. But using “= 0” or “< 1” simply reverts to the “Show had two coins”. Is that not possible?
Try taking the if/then outside of the for loop. Something like this:
dim TextArray as string = array("one","two","three")
foo = "She had two coins"
for each t in TextArray
foo = replaceall(foo , t, "bad" )
next
if InStr(foo, "bad") > 0 then
TextArea.text = foo
end if
Your problem is that foo is changing, but because it now contains “bad”, you never put it back into the textarea. As soon as it changes, your test for <= 0 causes the textarea to not be updated with the modified value of foo.
Yes, like what Robert says, if you move the if outside of the for loop, it seems to work. Almost like the code is outrunning the replaceall method and reaches the InStr before ReplaceAll is done…if you move it outside it has enough time to update itself. Weird.
The problem is that the text was replaced in the second iteration of the loop. However, on the third iteration, there is no replacement and the test is repeated. What finally appears in the text field depends only on the result of the very last test. So, there’s no point including the test in the loop.
ohhhh I get it. It’s updating TextArea every time, and I’m only seeing the last test on “three”. Thank you for catching that, this is extremely clear now!
Actually, no. Without the IF statement, the TextArea is updated every time and you do see the results - foo doesn’t get reset, it will continue to contain “bad”. With the IF statement, the TextArea is only updated the first time. On the second and third loop, even though foo now contains “bad”, the TextArea isn’t being updated.
You need a completely different approach if you don’t want the overhead of updating the TextArea every time and/or quit once you hit the first match. I’m not really sure which you actually wanted to accomplish.
var pattern as string = String.FromArray( textArray, "\E|\Q" )
pattern = "\b(\Q" + pattern + "\E)\b"
var rx as new RegEx
rx.SearchPattern = pattern
if rx.Search( foo ) isa RegExMatch then
// foo contains one of the words in textArray
end if
(untested)
In your example, pattern would end up as:
\b(\Qone\E|\Qtwo\E|\Qthree\E)\b
\b is a word boundary. \Q...\E tells the engine to use what’s between those literally, ignoring the meaning of otherwise-special tokens.