Re: String parsing question.
On Sun, 19 Apr 2009, Arne Vajh?j wrote:
SpreadTooThin wrote:
I need to build a string based on the contents of another string.
(This string will be used to create a directory structure, but that's
irrelevant, I think.)
String dirName = "$PatientID/$StudyID/$SeriesID/Example - $ImageUID";
I need to parse this into a different string where the $Names have
been replaced with actual data.
So it might look something like:
constructedDir = "John Smith/Brain MRI/Sagital slices/Example - Image
1";
What String methods or classes might help me do this simply?
Anything wrong with:
String dirName = "$PatientID/$StudyID/$SeriesID/Example - $ImageUID";
String constructedDir = dirName.replace("$PatientID", "John
Smith").replace("$StudyID", "Brain MRI").replace("$SeriesID", "Sagital
slices").replace("$ImageUID", "Image1");
?
Looks good to me.
One elaboration you might consider would be to get the $Names dynamically.
For instance, if you get the image info as a map:
// this is not real java syntax but the real syntax is too longwinded
Map<String, String> imageInfo = {
"PatientID": "John Smith",
"StudyID": "Brain MRI",
"SeriesID": "Sagital slices",
"ImageUID": "Image1"
};
And the template as a string:
String template = "$PatientID/$StudyID/$SeriesID/Example - $ImageUID";
You could do the construction like so:
String constructPath(String template, Map<String, String> namesAndValues) {
String path = template;
for (Map.Entry<String, String> nameAndValue: imageInfo.entrySet()) {
String name = nameAndValue.getKey();
String value = nameAndValue.getValue();
// tip of the hat to Andreas here:
if (value.contains("$")) throw new IllegalArgumentException("values cannot contain $ signs: name = " + name + ", value = " + value);
path = path.replaceAll(("$" + name), value);
}
// optional:
if (path.contains("$")) throw new IllegalArgumentException("not all names were supplied with values in path format: format = " + format + " + ", names and values = " + namesAndValues);
return path;
}
Also, there is something in the library you could apply -
java.text.MessageFormat. You'd have to rewrite your pattern like so:
String template = "{0}/{1}/{2}/{3}/Example = {4}";
And then do:
// you should do the following line once, and then keep the MessageFormat object
MessageFormat pathFormat = new MessageFormat(template);
String constructPath(String template, String patientID, String studyID, String seriesID, String imageUID) {
return pathFormat.format(new String[] {patientID, studyID, seriesID, imageUID});
}
If you were desperate to keep the $-based format, you could write
something which translated that to a MessageFormat format. You might also
need to write something to map between the names and indexes in the format
array, depending on how the input arrives.
tom
--
curry in a sack