How to ‘normalize’ X12 delimiters prior to processing content

Delimiters specified in the interchange. Translator’s x12 module expects standard delimiters to be present in processed data.

We can ‘normalize’ delimiters prior to processing, and revert back if needed after the processing.

We can specify non-standard delimiters in respective vmd file, but on this page we can see alternative approach using simple Lua scripting.

The ISA segment has very strict grammar and we know number of each byte representing specific delimiter.

The data element separator is byte number 4. The component element separator is byte number 105. The segment terminator is the byte that immediately follows the number 105.

Using scripting approach, we can easily compensate for presence of <CR><LF> as Segment Terminator or following Segment Terminator, something that might be tricky if we would be using a VMD file to declare non-standard delimiters.

Personally, I would have chosen to ‘normalize’ every EDI interchange delimiters, as a routine, before processing the content data.

Using the project and sample data from page How to approach X12 parsing, we add functionality.

function normalizeDelimiters(d)
   local function ST() -- segment terminator
      if d:find('GS') == 107 then 
         return true
      end
      return false
   end

   local function CES() -- component element separator
      if d:sub(105,105) == ':' then 
         return true
      end
      return false
   end

   local function DES() -- data element separator
      if d:sub(4,4) == '*' then 
         return true
      end
      return false
   end

   if ST() then 
      d = d:gsub(d:sub(106,106),'~')
   else
      d = d:gsub(d:sub(106,108),'~')
   end

   if not CES() then d = d:gsub(d:sub(105,105),':') end
   if not DES() then d = d:gsub(d:sub(4,4),'*') end

   return d
end

function main()  

   local function readMyFile(fn)
      local f = assert(io.open(fn, 'rb'))
      local d = f:read('*a')
      f:close()      
      return d
   end

   local Data = readMyFile('/Users/levblum/270BlueCrossEdited.edi')

   -- Match message delimiters to standard values 
   Data = normalizeDelimiters(Data) 

   local In,Name,Warnings = x12.parse{
      vmd = 'example/270v3.vmd', 
      data = Data}

   trace(In)

end