4
$\begingroup$

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.

$\endgroup$
1
  • $\begingroup$ ImportString[#, "CSV"] could be helpful for splitting... $\endgroup$
    – BlacKow
    Mar 11, 2016 at 16:02

2 Answers 2

4
$\begingroup$

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.

$\endgroup$
1
  • $\begingroup$ 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... $\endgroup$
    – AxelF
    Mar 14, 2016 at 7:14
3
$\begingroup$
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,                       "}
*)
$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.