RegEx question

RegEx makes my head hurt most of the time. Is there a way to detect which characters in one string are also present in another string? For these two strings:

BCH
ACEFHK

the returned result would be: CH Each string can be of varying lengths but can only have the characters A to K in them. I’ve read the language reference, and an article in RS Developer, but just can’t come up anything that works. Surely I am missing something very simple. Currently I just loop through the first string character by character and use Instr on the second string. Has to be a better way with RegEx, just can’t figure it out. Any help is appreciated.

** Well Strike that as I missed the “Compare Part” in which RegEx is your best bet. Hopefully Kem will sign on since he knows more than we want to know about RegEx :slight_smile:

Thanks, Mike, but Instr is what I am currently using. Hoping to find a one shot method using RegEx.

Take either string and use it to do a replace on the other like this:

dim rx as new RegEx
rx.SearchPattern = "[^" + string1 + "]"
rx.ReplacementPattern = ""
rx.Options.ReplaceAllMatches = true
dim result as string = rx.Replace( string2 )

This means, remove letters that are not in string1. The result will be letters that are in both.

Of course, if the target string has dups like “ACEFHKACEFHK”, you will end up with “CHCH”. This pattern would remove those dups:

dim dupRemoverRX as new RegEx
dupRemoverRX.SearchPattern = "(.)(?=.*\\g1)"
dupRemoverRX.ReplacementPattern = ""
dupRemoverRX.Options.ReplaceAllMatches = true
result = dupRemoverRX.Replace( result )

There are number of ways to do this, of course.

You could also do this with a Dictionary, something like this:

dim chars() as string = string1.Split( "" )
dim d as new Dictionary
for each letter as string in chars
  d.Value( letter ) = nil
next

dim matches() as string
chars = string2.Split
for each letter as string in chars
  if d.HasKey( letter ) then matches.Append letter
next

dim result as string = join( matches, "" )

There won’t be any duplicates in the result here, and you can even sort matches before you turn it back into a string.

Thanks for the reply Kem, much appreciated. There are no dupes so I think the first thing suggested looks very workable. Let me try to get my head around this and see if I can make it work. Thanks again, I’ll mark as answered if I can get this to work.

Wow, works like a charm! I would have never thought to approach it that way, with Replace. Programmers like me need a push from time to time. Thanks again for the prompt, insightful help!

My pleasure.

Just for the record, there was a mistake in the Dictionary version, so here is the correct code to avoid dupes:

dim chars() as string = string1.Split( "" )
dim d as new Dictionary
for each letter as string in chars
  d.Value( letter ) = nil
next

dim matches() as string
chars = string2.Split
for each letter as string in chars
  if d.HasKey( letter ) then
    matches.Append letter
    d.Remove letter
  end if
next

dim result as string = join( matches, "" )