Remove selected characters from any HL7 field for any message, master string.gsub() replacements

Say we have PID-5 field (Patient Name) is contaminated with extra characters like ‘#’ and ‘+’, e.g., ‘MODA#L+ITY^241’, and they have to be removed before message is forwarded to its destination.

Moreover, we want to process any HL7 message except ADT messages.

Here is our solution.

First we filter out any ADT messages;  then we split the message and replace characters in Patient Name only; later join message back together and final result, clean message, is pushed back to Iguana queue.

Our contaminated and cleaned messages are shown below. Notice how the extra characters have been removed from Patient Name (PID-5).

… and complete code is below

require('split')

function main(Data)
  In, MsgName = hl7.parse{data=Data, vmd='19320.vmd'}

  if MsgName == 'CatchAll' then
    iguana.logInfo('Filtered '..In.MSH[9][1]..'^'
        ..In.MSH[9][2]..' Msg Control ID '..In.MSH[10])
   return
  end

  local s1 = In.PID[5][1]:S():gsub('[$().*+?^%-%[%]%%]','%%%1')
  local s2 = In.PID[5][1]:S():gsub('[#%+]', '')  
  local S = Data:segments()
  local a,b =Data:findSegment('PID')

  S[b] = a:gsub(s1,s2)  
  queue.push{data=JoinMsg(S)}
end

function JoinMsg(S)
  local r = S[1]..'\r'
  for i = 2, #S do r = r..S[i]..'\r' end
  return r
end

… along with respective vmd file, to match any message that has PID segment

19320.vmd

… and code snippet for module ‘split’.

Note: In Iguana version 5.6.16 we added the string.split() function to Iguana’s standard string library to split strings on a specified delimiter, this removes the stringutil module dependency.

If you are using a version before 5.6.16 you can use string.split() function in the stringutil module.

-- Useful extension string method
function string.split(Input,sep)
   local fields = {}
   local pattern = string.format("([^%s]*%s?)", sep,sep)
   for match in Input:gmatch(pattern) do
      local lastchar = match:sub(-1)
      if (lastchar == sep) then 
         fields[#fields+1] = match:sub(0,-2)
      elseif (#lastchar > 0) then
         fields[#fields+1] = match
      end
   end
   --This part handles the case where if a delimiter
   --ends a string, it should be considered a new entry
   --e.g. 123| should be 2 fields: ['123','']
   if Input:sub(-1) == sep then
      fields[#fields+1] = ''
   end
   return fields
end

function string.segments(s)             
   return s:split('\r')
end   

function string.findSegment(s,name)
   local S=s:segments()
   for i = 1, #S do
      if S[i]:sub(1,4) == name..'|' then
         return S[i],i
      end
   end
   return 
end

Complete Lua Character Classes reference is available at 5.4.1 – Patterns, Character Class