› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › Removing curly braces
OBX|2|TX|SC05-4$rpt^^99DHT|||SOURCE: {Endocervical Pap Smear}|||||F
When I try to join it back into the message, I get an error about “list element followed by ||||F instead of space.” I have tried removing the curly braces, but have not be successful. Anybody know how to get rid of them?
Here is one way using string map:
hcitcl>set var “SOURCE: {Endocervical Pap Smear}”
SOURCE: {Endocervical Pap Smear}
hcitcl>string map {{ {} } {}} $var
SOURCE: Endocervical Pap Smear
Hope this helps…
Tom Rioux
You could do something like …
regsub -all — {{}} $var “” var
.
-- Max Drown (Infor)
The string map line works as long as I run it through a variable. Thanks for both of your input.
This looks like you have an error in your proc.
Does the raw data actually have curly braces as part of the data?
If not, you have an element from a list instead of string of data.
Are you sure you want to remove the braces instead of fixing the problem?
Michael, that is what I am experimenting with. I would like to use regexp to find the data in OBX 5, and then use lsearch to return the list postition number.
If you’d like to post what you have so far, we could look at it for you.
Michael, I was able to get the OBX 5 isolated earlier this week, but had a brainstorm and made some big changes without saving a copy, and am now getting an “list element in quotes followed by “.” ” error, but this is what I have so far.
proc datadump { args } {
keylget args MODE mode ;# Fetch mode
set dispList {}
set signed_flag “”
switch -exact — $mode {
start {
# Perform special init functions
# N.B.: there may or may not be a MSGID key in args
}
run {
# ‘run’ mode always has a MSGID; fetch and process it
keylget args MSGID mh
set msg [msgget $mh]
set fieldSep [string index $msg 3]
set segmentList [split $msg r]
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
#echo $obx
set obxlist “”
foreach segment in $obx {
set field [lindex [split $segment $fieldSep] 5]
lappend obxlist “$field”
}
echo $obxlist
set find [lsearch $source {SOURCE:}]
set list [lsearch $source {}]
Forgot a line
proc datadump { args } {
keylget args MODE mode ;# Fetch mode
set dispList {}
set signed_flag “”
switch -exact — $mode {
start {
# Perform special init functions
# N.B.: there may or may not be a MSGID key in args
}
run {
# ‘run’ mode always has a MSGID; fetch and process it
keylget args MSGID mh
set msg [msgget $mh]
set fieldSep [string index $msg 3]
set segmentList [split $msg r]
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
#echo $obx
set obxlist “”
foreach segment in $obx {
set field [lindex [split $segment $fieldSep] 5]
lappend obxlist “$field”
}
echo $obxlist
set source $obxlist
set find [lsearch $source {SOURCE:}]
set list [lsearch $source {}]
Try this:
set segmentList [split $msg r]
set obx [lsearch -regexp $segmentList ^OBX]
foreach segment in $obx {
set field [lindex [split $segment $fieldSep] 5]
lappend obxlist “$field”
}
echo $obxlist
set source $obxlist
set find [lsearch -regexp $obxlist SOURCE:]
#set find [lsearch $source {SOURCE:}]
#set list [lsearch $source {}]
Got it working, thanks. Here is what $obxlist looks like. So what I am trying to do is grab everything from SOURCE: to the blank before FINAL CYTOLOGIC DIAGNOSIS: I am thinking that some regexp expression might do it, but I can’t seem to get the sytntax right. Any ideas?
**** GYNECOLOGICAL CYTOLOGY REPORT *****
CASE STATUS: Signed Out
PATIENT NAME:test, silly
CASE NUMBER: SC05-4
DATE COLLECTED:4/28/2005
SOURCE:
Endocervical Pap Smear
FINAL CYTOLOGIC DIAGNOSIS:
NEGATIVE FOR INTRAEPITHELIAL LESION OR MALIGNANCY.
Cytologically benign endocervical-type glandular cells present.
Sorry, I’m not very good at regexp
Is this a list? It is little wonder you are have problems with braces as that is the internal quoting.
Let’s assume it is a list, if not omit the first step
set obxstring [join $obxlist { }]
set source “” ;# just in case
regexp — {.*(SOURCE:.*?)FINAL CYTOLOGIC DIAGNOSIS:}
$obxstring {} source
# Get rid of lf
set source [string trim $source]
Unless I completely misunderstand the problem 🙂
regexp — {.*(SOURCE:.*?)FINAL C…DIAGNOSIS:} $obxstring {} source
Gives me an “extra characters after close brace” error, do I have the syntax right?
The backslash was a line contiuation. You don’t need if all on one line
Gotcha, the regexp is running but I am not getting anything returned. If I wanted to have it grab everything from SOURCE: to the blank space before FINAL CYTO.., would I just put a “” after the .*?) It is interesting that all the elements of obxstring are enclosed in {} except SOURCE:. I added an lappend field “$obxlist” after the set obxlist [lindex [split $segment $fieldSep] 5] line to get the {}.
{***** GYNECOLOGICAL CYTOLOGY REPORT *****}
{}
{CASE STATUS: Signed Out }
{PATIENT NAME:test, silly}
{CASE NUMBER: SC05-4}
{}
{DATE COLLECTED:4/28/2005}
SOURCE:
{Endocervical Pap Smear}
{}
{FINAL CYTOLOGIC DIAGNOSIS:}
That is because you have a list! You must remove it from the list context to deal with it as a string!
To add a little more detail to Charlie’s answer. “SUCCESS:” doesn’t need to be “grouped” because there are not embeded white space. Since these are all list elements, each element has to be grouped if there is white space or else each word would become its own element. Tcl (and the Engine) does this for you by sticking in curly braces as necessary. In the case of SUCCESS: no grouping brackets are needed, but for the others with white space brackets are added to delineate (or group) the parts of one element together.
I hope this helps
Kevan Riley
Sr. Integration Analyst
Adventist Health System – IS
Lake Mary, FL
What command would you use to group the elements together as a string?
I usually “delist” with lindex, and there is a “list” command to form a list.
e.g.
set a [list “CASE STATUS: Signed Out” “PATIENT NAME:test, silly” “CASE NUMBER:
Yes, thanks. So according to Charlie, if I group the list as a string, the regexp should work. I am interpreting Charlie’s script correctly, it is grabbing everything from SOURCE: to the end of DIAGNOSIS. Would carriage returns be preventing it from returning the requested characters?
Right, looking back over what Charlie wrote, I realized i missed the “join” (set obxstring [join $obxlist { }]). Join “de-lists” a list into a string. That is, it un-groups all of the elements, joining them with, in this case, a space. So your end result from Charlie’s join is a string that is no longer grouped into list elements.
One test, is to echo out an llength or your list (puts [llength $obxlist]) and see if the number matches the number of elements you think you should have. If you think you have 5 subfields in a list, and llength yields something like 9 or 1, then you want to echo out your “list” and see what is going on. Either, the subfields are not grouped, in which case every space deliniates a new list element even if it is just a two word description, or it has been “over grouped, and is a list of one element, that possibly contains a list (think {{pt one} {pt two}}).
One more thing to keep in mind. Technically speaking a list is just a specially formatted string. You can use the list commands like lindex, list, lappend, etc. and I recommend that, but you can also treat a list as a string, but it is more complicated because, you then, are the one that has to be sure to account for and deal with existence or need for curly braces.
For instance, you can set a return disposition list for a Tcl UPoc proc like this:
set displist “”
lappend dispList “CONTINUE $mh”
return $displist
or
set displist “{CONTINUE $mh}”
return $displist
or even
return “{CONTINUE $mh}”
The first form is preferred since it allows the native commands to handle the curly braces for you (it is also good Cloverleaf programing practice, since the displist could contain more that one disposition).
Another example:
You could get the first element of a list by something like this:
set a
puts $a
-> {pt one} {pt two}
set i1 [expr [string first “{” $a] +1]
set i2 [expr [string first “}” $a] -1]
set b [string range $a $i1 $i2]
puts $b
-> pt one
or you could just do:
set b [lindex $a 0]
puts $b
-> pt one
hope this helps.
PS. I tested Charlies code against teh list you posted in the in initial post and I got “SOURCE: Endocervical Pap Smear” out.
Thanks again for your input. The llength command is useful. When I run the lappend, and check the llength of obxlist, I get a list of subfields with a value of 1. If I run a regexp -inline of obxlist, it returns both SOURCE: and FINAL CYTO… Charlie’s regexp script still returns nothing.
You probably want to use “append” not “lappend”. Try that.
Append seems to have the same effect as not running lappend. The subfields have variable llength values, and the regexp -inline returns nothing for FINAL CYTO…
Perhaps you should repost your code. I am not sure I am following along. Are you doing the “join”? I don’t think you want any of this in a list at all. I think you want to join it all in to one long string. At that point your “regexp” will work. Try echoing out your variable you are trying to “regexp” against. If there are still curly braces in there, they it hasn’t been joined correctly.
proc datadump { args } {
keylget args MODE mode ;# Fetch mode
set dispList {}
set signed_flag “”
switch -exact — $mode {
start {
# Perform special init functions
# N.B.: there may or may not be a MSGID key in args
}
run {
# ‘run’ mode always has a MSGID; fetch and process it
keylget args MSGID mh
set msg [msgget $mh]
set fieldSep [string index $msg 3]
set segmentList [split $msg r]
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
foreach segment $obx {
set obxlist “”
set field [lindex [split $segment $fieldSep] 5]
string trim $field
append obxlist “$field”
set obxstring [join $obxlist {}]
set trim “”
set finder [lsearch -inline -regexp $obxlist {FINAL CYTOLOGIC DIAGNOSIS:}]
set length [llength $obxlist]
set site [lsearch $field {SOURCE:}]
regexp — {.*(SOURCE:.*?)FINAL CYTOLOGIC DIAGNOSIS:} $obxlist {} trim
echo $finder
}
Kevan, here is the business end of the proc. I have substituted some of the variable fields for testing. I agree with your assesment of needing to get the data formatted as a string. I am running this through the Testing Tool, and can provide the test file if you want.
What exactly are you trying to do with the message?
(I’ve tried to read through the thread, but it’s confusing)
And could you please post an entire sample inbound message?
-- Max Drown (Infor)
Max, what I am trying to do is read through all the OBX 5 values, and pull out everyting from SOURCE: to the blank line above FINAL CYTOLOGIC DIAGNOSIS:
OBX|1|TX|SC05-4$rpt^^99DHT||***** GYNECOLOGICAL CYTOLOGY REPORT *****||||||F
OBX|2|TX|SC05-4$rpt^^99DHT||||||||F
OBX|3|TX|SC05-4$rpt^^99DHT||CASE STATUS: Signed Out ||||||F
OBX|4|TX|SC05-4$rpt^^99DHT||PATIENT NAME:test, silly||||||F
OBX|5|TX|SC05-4$rpt^^99DHT||CASE NUMBER: SC05-4||||||F
OBX|6|TX|SC05-4$rpt^^99DHT||||||||F
OBX|7|TX|SC05-4$rpt^^99DHT||DATE COLLECTED:4/28/2005||||||F
OBX|8|TX|SC05-4$rpt^^99DHT||SOURCE:||||||F
OBX|9|TX|SC05-4$rpt^^99DHT||Endocervical Pap Smear||||||F
OBX|10|TX|SC05-4$rpt^^99DHT||||||||F
OBX|11|TX|SC05-4$rpt^^99DHT||FINAL CYTOLOGIC DIAGNOSIS:||||||F
OBX|12|TX|SC05-4$rpt^^99DHT||NEGATIVE FOR INTRAEPITHELIAL LESION OR MALIGNANCY.||||||F
OBX|13|TX|SC05-4$rpt^^99DHT||Cytologically benign endocervical-type glandular
I set up a little test environment using a file called tmp.tcl. After making changes to the code, I run the code from the command line by typing “tcl tmp.tcl”. The output is printed to the screen.
Test messge (^M == carriage rerturn just like in normal HL7):
set msg “MSH|^MOBX|1|2|3|4|SOURCE: test1 FINAL CYTOLOGIC DIAGNOSIS:^MOBX|1|2|3|4|SOURCE: test2 FINAL CYTOLOGIC DIAGNOSIS:^MOBX|1|2|3|4|SOURCE: test3 FINAL CYTOLOGIC DIAGNOSIS:^MOBX|1|2|3|4|SOURCE: test4 FINAL CYTOLOGIC DIAGNOSIS:^M
Script:
set fieldSep [string index $msg 3]
set segmentList [split $msg r]
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
foreach segment $obx {
set field [lindex [split $segment $fieldSep] 5]
set resultList [regexp -inline -all — {SOURCE: (.*?) FINAL} $field]
puts [lindex $resultList 1]
}
Result:
test1
test2
test3
test4
-- Max Drown (Infor)
Mark,
I see two errors in the code you posted…
1) your ‘set obxlist “”‘ statement needs to be moved out of your foreach loop.
2) You string trim is missing its set, it should be ‘set field [string trim $field]’
Here is my recommendation:
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
Here’s some sample code based on your message (demonstrating regexp inline switch).
set fieldSep [string index $msg 3]
set segmentList [split $msg r]
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
foreach segment $obx {
[code]set fieldSep [string index $msg 3]
set segmentList [split $msg r]
set obx [lrange [lregexp $segmentList {^OBX}] 0 end]
foreach segment $obx {
-- Max Drown (Infor)
Max, with the set obx5list moved out of the foreach, all I get for $obx5list is the last OBX 5 of the message appended on.
Kevan, your’s worked. Yahoo! Can’t thank all those who directed their massive brain power on this, and I promise to never create a thread this long again.