# How would I split a string into substrings ending with a delimiter and a maximum length?

I have a list of parameters, formatted as a string of integers and reals in both simple and scientific notation, with a comma as delimiter. A short sample:

parameterString="126,10,3,1,0,0,0,0.0,0.0,0.0,0.0,0.4890289E+00,0.5741907E+00,0.6593526E+00,0.7445144E+00,0.8296763E+00,0.1000000E+01,0.1000000E+01,0.1000000E+01,0.1000000E+01,"


I need to break this into lines of at most 65 characters, where the last character has to be a space. The last non-space character has to be a delimiter, the rest will be padded with spaces. I would like fit as many parameters on a each line as possible. So far, I've found only a rather clumsy loop approach:

parameters=StringSplit[StringReplace[StringJoin@@parameterString,{" "->"","D"->"E"}],","]

full={};count=1;
While[count<=Length[parameters],
s="";
While[count<=Length[parameters]&&StringLength[s]+StringLength[parameters[[count]]]+1<65,
s=StringJoin[s,parameters[[count]],","];count++
];
full=Append[full,s]
]

blank=StringRepeat[" ",65];
full=full/.s_String:>StringReplacePart[blank,s,{1,StringLength[s]}];


It does the job, but I wonder if there is a more elegant solution to it, maybe a clever combination of StringSplit and StringPartition.

To put this into context: I am exporting splines in IGES, a standardized file format for CAD. I am aware that there are export formats available like DXF, but I never got them to work exactly as we need it.

• ImportString[#, "CSV"] could be helpful for splitting... – BlacKow Mar 11 '16 at 16:02

Here's one approach that uses a regular expression to match up to 63 characters and a delimiter. Then that gets padded out to 65:

In[67]:= parameterString =
"126,10,3,1,0,0,0,0.0,0.0,0.0,0.0,0.4890289E+00,0.5741907E+00,0.6593526E+00,0.7445144E+00,0.8296763E+00,0.1000000E+01,0.1000000E+01,0.1000000E+01,0.1000000E+01,";

In[68]:= spaces = StringJoin[Table[" ", 63]];

In[69]:= StringCases[
parameterString,
RegularExpression["(.{1,64},)"] :> StringTake["$1" <> spaces, 65] ] Out[69]= { "126,10,3,1,0,0,0,0.0,0.0,0.0,0.0,0.4890289E+00,0.5741907E+00, ", "0.6593526E+00,0.7445144E+00,0.8296763E+00,0.1000000E+01, ", "0.1000000E+01,0.1000000E+01,0.1000000E+01, " }  It assumes that you don't have any 65+ digit characters. In newer versions, you can use StringPadRight["$1", 65] instead of the StringTake[..] construction.

• I've accepted your answer since it came first. Dr. belisarius had basically the same idea. Looks like I should polish my knowledge of regular expressions... – AxelF Mar 14 '16 at 7:14
StringJoin /@ (PadRight[#, 65, " "] & /@  Characters /@
StringCases[parameterString, RegularExpression@".{1,63}\,"])

(*
{
"126,10,3,1,0,0,0,0.0,0.0,0.0,0.0,0.4890289E+00,0.5741907E+00,    ", \
"0.6593526E+00,0.7445144E+00,0.8296763E+00,0.1000000E+01,         ", \
"0.1000000E+01,0.1000000E+01,0.1000000E+01,                       "}
*)