With a fixed length you can use StringTake and set the region you like
StringTake[#, {12, 11 + 20 + 10}] & /@
{" 109Lemon Chiffon 25:22:29 6519218 ",
" 2082Mint Cream 39:24:41 7314284 ",
" 6790Indian Red 21:57:53 3368766 "}
(*
Lemon Chiffon 25:22:29
Mint Cream 39:24:41
Indian Red 21:57:53
*)
Update
You noted, that the creation of the appropriate region for StringTake is maybe tedious. For this, you can write a function which takes your word boundaries and the columns you want to extract and returns another function, an extractor which can take one string and extracts the appropriate columns. This has the advantage that you have to give the word boundaries and the columns only one time and can use the extractor as often as you like.
Taking your {11, 20, 10, 9} boundaries as example, the integral part of the function is a combination of Accumulate, Partition and a Map which adds 1 to the start position of each word region.
({#1+1,#2}&@@@Partition[Accumulate@{11,20,10,9},2,1])
(* {{12,31},{32,41},{42,50}} *)
As you see you get exactly the positions you need for StringTake, e.g. first word goes from 12 to 31, etc. Surely, you don't want all words from a string, because then you wouldn't need a selector, but wouldn't it be nice, if you could use the same syntax as you can use for Part, namely specify single elements {1,2,3,5} or ranges {1;;3, 5}? This is done in the second part of our selector, where we use a string which needs to be filled:
dataSelector[columns_, wordlengths_] :=
With[{wordregions = ({#1 + 1, #2} & @@@
Partition[Accumulate@Prepend[wordlengths, 0], 2, 1])},
Function[string, StringJoin[StringTake[string, #] & /@
(Part[wordregions, #] & /@ columns)]]]
The usage is now simple: with in being your sample data you can do
in={" 109Lemon Chiffon 25:22:29 6519218 ",
" 2082Mint Cream 39:24:41 7314284 ",
" 6790Indian Red 21:57:53 3368766 "};
dataSelector[{4,2;;3,1},{11,20,10,9}]/@in
(*
{6519218 Lemon Chiffon 25:22:29 109,
7314284 Mint Cream 39:24:41 2082,
3368766 Indian Red 21:57:53 6790}
*)
Update regarding comment
Yes, you are right, the first word could not be extracted but since it always ranges from 1 simply prepending 0 before calling Accumulate in the dataSelector function fixes the problem. Additionally, when you use the dataSelector to extract the say second and third word it returns a list of strings. When I look now at your sample, you maybe prefer to have one string back where all selected words are concatenated. I added the appropriate StringJoin to the function.
Depending on your level as Mathematica programmer, my dataSelector is a bad example since it's probably a bit harder to understand. When you want to create the output as in your last example with it, you have to use it like:
dataline = {" 1556Floral White 29:48:49 7856900 "};
sel = dataSelector[{2, 3}, {11, 20, 10, 9}];
sel[dataline]
(* "Floral White 29:48:49 " *)
or, if you want to extract the second and third word for a list of strings, you simply use sel /@ in. The important line to understand is the second. To create a selector function, you call for instance dataSelector[{2, 3}, {11, 20, 10, 9}] where {2,3} are the words you want to extract and the last parameter is the length of each word.
Important here is, that you can use the range specification ;; and All like you can use it with Part ([[]]). Test for instance the output of the following examples
dataSelector[{All}, {11, 20, 10, 9}][dataline]
dataSelector[{1, 3 ;; 4}, {11, 20, 10, 9}][dataline]
dataSelector[{1, All, 2 ;; 4}, {11, 20, 10, 9}][dataline]
Update 2
When your goal is speed, then you should call StringTake[{s1,s2,...},{spec1,spec2,...}], this means you input all your datasets {s1,s2,...} in one call and you put all wordboundary specs in a list. This should be reasonable fast.
Your update contains the undefined variable wb. Would you mind to measure your method against the method below with the 4000000 elements in data?
data = RandomChoice[
{" 109Lemon Chiffon 25:22:29 6519218 ",
" 2082Mint Cream 39:24:41 7314284 ",
" 6790Indian Red 21:57:53 3368766 "}, 4000000];
dataSelector[columns_, wordlengths_] :=
With[{wordregions = (Part[({#1 + 1, #2} & @@@
Partition[Accumulate@Prepend[wordlengths, 0], 2,
1]) , #] & /@ columns)},
Function[string, StringJoin @@@ StringTake[string, wordregions]] ]
f = dataSelector[{2, 3}, {11, 20, 10, 9}];
AbsoluteTiming[f[data]] // First
datelineas a list, as in{{109, "Lemon Chiffon"}, {25, 22, 29}, 6519218}. Even if I were only interested in displaying the data, I would use a list rather than a string. – David Carraher Dec 30 '12 at 14:14