Okay.... This is going to be a
bit trickier. Because for properly formatted CSV data, any string with embedded newlines needs to be quoted with double quotes. For example, the result for your data needs to look like:
Code:
param1,param2,"sub1
sub2
sub3",param4,param5
What we need to do then, is grab the field(s) with colon-separated subfields, put double quotes around it, and substitute all ":" characters with newlines. Although it might be theoretically possible to do all that in a single
regsub command with a single regular expression, I don't feel up to putting that beast together.
Instead, I'm going to break it down into two separate substitutions. First, I'll use
regsub to locate all field(s) with colon-separated subfields. As the replacement text, I'll put double-quotes around the matched text. Then, I'll use Tcl's
string map command to perform the colon-to-newline replacement. (
string map was introduced in Tcl 8.1.1. It basically performs simple string substitutions, much like a
regsub with no wildcards, but can handle multiple A-to-B translations in a single pass. It's much faster than using
regsub for non-wildcarded string substitution. In fact, Tcl 8.4 introduced an "under-the-hood" optimization that basically translated non-wildcarded
regsubs at the bytecode level to equivalent
string maps.)
Code:
# Here's our test data
set data {param1,param2,sub1:sub2:sub3,param4,param5}
# Create a regular expression that will match a field
# containing an arbitrary number of colon-separated
# subfields.
set pat {[^,:]*(:[^:,]*)*:[^,]*}
# Run our regsub command to find all colon-separated
# subfields and double-quote them.
regsub -all $pat $data {"&"} result
# Now map all our colons to newlines.
set final [string map [list : \n] $result]
# Let's look at what we've got
puts $final
If this seems to work for you, it would be best, of course, to stick it all in a procedure to hide the grungy details.
Then, you can take all these massaged strings and write them out to your CSV data file, like we discussed earlier.
- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting,
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax