› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › Converting free text name field to Lastname^Firstname^I
|LASTNAME, FIRSTNAME MI|
Receiving system need IN1-16 in this format
|LASTNAME^FIRSTNAME^MI| which would be IN1-16.1, IN1-16.2 and IN1-16.3
Being free text, it is not certain that sending system with be consistant.
Can this be done and how ? I’m at a loss and am fairly new to cloverleaf.
Computers are “RULE” based machines. If you cannot come up with a consistent rule it will be very hard to parse the inbound data.
Given the inbound field will be as defined with possible multiple spaces:
In translate define Input field as IN1.#16[0] and Outbound as IN1.#16.[0] IN1.#16.[1] IN1.#16.[2]
In a Tcl fragment:
set inpList [split [lindex $xlateInVals 0] ,]
set LAST [lindex $inpList 0]
set FIRST [lindex [lindex $inpList 1] 0]
set MID [lindex [lindex $inpList 1] 1]
set xlateOutVals
This will handle spaces in the last name but not the first name
set inpList [split [lindex $xlateInVals 0] ,]
set LAST [lindex $inpList 0]
set part [lindex $inpList 1]
set last_space [string last ” ” $part]
set FIRST [string trim [string range $part 0 $last_space]]
set MID [string trim [string range $part $last_space end]]
set xlateOutVals [list $LAST $FIRST $MID]
This way everything after the last space in the first/middlename part of the name, will be considered middle name; before the last space is the first name.
Zuyderland Medisch Centrum; Heerlen/Sittard; The Netherlands
We’ve been using the attached tcl proc to to parse the free-text name into standard HL7 name format:
LastName^FirstName^MiddleInitial^Suffix^Prefix^Degree
The attached proc calls this table lookup proc to extract a suffix, prefix, degree and/or baby designator:
proc xlt_ccTagNameElement {element} {
set tag {noTag}
switch -exact — $element {
JR – SR – II – III – IV – 2ND – 3RD – 4TH {
set tag {suffix}
}
MS – MR – MRS {
set tag {prefix}
}
MD – DR – PHD {
set tag {degree}
}
BB – BBA – BBB – BBC – BBD – BBE – BBF –
BG – BGA – BGB – BGC – BGD – BGE – BGF {
set tag {baby}
}
}
return $tag
The procs have been working reasonably well for the past 9 years. Occasionally we’ll have a problem where strange things come out of HIS, but it’s pretty rare that we have to manually intervene and “fix” a name.
As Charlie noted, you will never get a perfect parse 100% of the time when trying to convert free-text into discrete elements.
– Glenn
xlt_parse_name.tcl is the proc we have been using to help fix our malformed patient names:
# Begin Module Header ==========================================================
#
# —–
# Name:
# —–
#
# xlt_parse_name.tcl
#
# ——–
# Purpose:
# ——–
#
# Parse out the last_name first_name middle_initial
# and return the desired name specified.
#
# ———–
# Input Args:
# ———–
#
# $xlateInVals 0 – entire_name
# $xlateInVals 1 – the desired name to return via $xlateInVals 0
# valid valuse are
#
# first (returns first name only)
# middle (returns middle initial only)
# last (returns last name only)
# last^first^middle (returns entire name in HL7 delimited format)
#
# ———–
# Output Args:
# ———–
#
# $xlateOutVals 0 – the desired name
#
# ——
# Notes:
# ——
#
# Example of Normal Usage:
#
# refer to $HCIROOT/test_russ/parse_hl7_v23_name.xlt
# refer to $HCIROOT/test_russ/parse_flat_name.xlt
#
# Example of name variations tested for desired_name = “last^first^middle” :
#
# name_in name_out
# ——- ——–
# 01) Ross^Russ^K Ross^Russ^K
# 02) Ross^Russ Ross^Russ
# 03) Ross^Russ^ Ross^Russ
# 04) Ross^Russ^, Ross^Russ
# 05) Ross^Russ K Ross^Russ^K
# 06) ^Russ^ ^Russ
# 07) ^Russ ^Russ
# 08) Ross^ Ross
# 09) Ross, Russ K Ross^Russ^K
# 10) Ross ,Russ K Ross^Russ^K
# 11) Ross, Russ Ross^Russ
# 12) Ross, Russ, Ross^Russ
# 13) Ross, Russ,^ Ross^Russ
# 14) Ross ,Russ Ross^Russ
# 15) Ross ,Russ, Ross^Russ
# 16) Ross ,Russ,^ Ross^Russ
# 17) Ross, Russ Jr. K Ross^Russ Jr^K
# 18) Ross ,Russ Jr. K Ross^Russ Jr^K
# 19) Ross, Russ III, K Ross^Russ III^K
# 20) Ross ,Russ III ,K Ross^Russ III^K
# 21) De La Cruz, David De La Cruz^David
# 22) De La Cruz ,David De La Cruz^David
# 23) Ross Ross
# 24) De La Cruz De La Cruz
# 25) Ross^ ^ Ross
# 26) Ross^^K Ross^^K
# 27) Russ K Russ^^K (this case works as programmed)
# 28) Ross^^ Ross
# 29) Ross^R^K Ross^R^K
# 30) Ross^R Ross^R
# 31) Ross^R^ Ross^R
#
# UPoC type = xltp
#
# Assumes that the middle initial will be present
# if the last 2 characters are ” X” where X is the middle initial
# or the last 2 characters are “^X” where X is the middle initial
#
# All data is presented through special variables. The initial
# upvar in this proc provides access to the required variables.
#
# This proc style only works when called from a code fragment
# within an XLT.
#
# ——–
# History:
# ——–
#
# 1999.09.15 Russ Ross
# – wrote initial version.
#
# 2006.03.23 Russ Ross
# – probably modified to get rid of commas in the last_name
#
# 2007.05.30 Russ Ross
# – added logic to handle cases 30) and 31) above
# without impacting cases 01) – 29)
#
# End Module Header ============================================================
proc xlt_parse_name {} {
upvar xlateId xlateId
xlateInList xlateInList
xlateInTypes xlateInTypes
xlateInVals xlateInVals
xlateOutList xlateOutList
xlateOutTypes xlateOutTypes
xlateOutVals xlateOutVals
#————————————————-
# Set the input argument(s),
# since it is a list, also convert it to a string
#————————————————-
set name_in [string trim [lindex $xlateInVals 0]]
set desired_name [string trim [lindex $xlateInVals 1]]
#
#———————-
# initialize varibales
#———————-
set first_name “”
set middle_initial “”
set last_name “”
# Note: a blank can not be a name delimiter
# —————————————–
set name_delimiters “^,”
#————————-
# pre-process the name_in
#————————-
regsub -all {.} $name_in ” ” name_in
regsub -all {_} $name_in ” ” name_in
set name_in [string trim $name_in ” “]
set name_in [string trimright $name_in “$name_delimiters “]
# puts “name_in=($name_in)”
#———————————-
# see if there is a middle initial
#———————————-
set iend [expr [string length $name_in]-1]
set istart [expr $iend-1]
set last_2_chars [string range $name_in $istart $iend]
set last_2_chars [string trim $last_2_chars ” “]
set last_2_chars [string trimleft $last_2_chars “$name_delimiters “]
if {[string length $last_2_chars] == 1} {
set middle_initial $last_2_chars
}
#—————————————————–
# check to to avoid glitch that occurs
# when the first name is one character
# and there is no middle initial (for example: Ross^R)
#—————————————————–
set split_first_name [lindex [split $name_in ^] 1]
set split_middle_initial [lindex [split $name_in ^] 2]
if {([string length $split_first_name] == 1) & ([string length $split_middle_initial] == 0)} {
set middle_initial “”
}
# echo “middle_initial=($middle_initial)”
#———————————————————————-
# trim any characters from the end of the name_in string
# so that name_in string only contains the last_name and/or first_name
#———————————————————————-
set last_first_name $name_in
if {$middle_initial != “”} {
set iend [expr [string length $name_in]-3]
set last_first_name [string range $last_first_name 0 $iend]
}
#————————————————-
# determine if there is a first and/or last name
#————————————————-
set iend [expr [string length $name_in]-1]
set last_first_name [string range $last_first_name 0 $iend]
set last_first_name [string trimright $last_first_name “$name_delimiters “]
# echo “last_first_name=($last_first_name)”
set iend [expr [string length $last_first_name]-1]
for {set i $iend} {$i >= 0} {incr i -1} {
set next_char [string range $last_first_name $i $i]
if {[string first $next_char $name_delimiters] != -1} {
# a name_delimiter has been found
# ——————————-
set first_name [string range $last_first_name $i $iend]
set first_name [string trim $first_name “$name_delimiters “]
set last_name [string range $last_first_name 0 $i]
regsub -all {,} $last_name “” last_name
set last_name [string trim $last_name “$name_delimiters “]
break
}
}
if {$i<0} {
# no name_delimiter was found so there is no first_name
# —————————————————–
regsub -all {,} $last_name "" last_name
set last_name [string trim $last_first_name "$name_delimiters "]
}
# echo "first_name=($first_name)"
# echo "last_name=($last_name)"
#————————————————-
# Set the output argument to the desired_name,
# since it is a string, also convert it to a list
#————————————————-
switch -exact $desired_name {
last^first^middle {
set name_out $last_name^$first_name^$middle_initial
set name_out [string trimright $name_out "$name_delimiters "]
}
first {
set name_out $first_name
}
middle {
set name_out $middle_initial
}
last {
set name_out $last_name
}
default {
echo "n ——————————————–"
echo "n Error in in TCL proc (xlt_parse_name)"
echo "n Bad xlate argument was passed to this module"
echo "n desired_name = ($desired_name)"
echo "n ——————————————–"
echo "n"
set name_out "error bad arg"
}
}
set xlateOutVals [list $name_out]
}
Russ Ross
RussRoss318@gmail.com