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