Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Given a list of strings:

data = {
 "2894;Hot Pink;53:09:44;1449714",
 "17456;Dark Cyan;19:06:42;6929227",
 "5147;Lime;54:11:55;5247632"
}

(Words are separated by ";", the number of words in strings are equal. Number of characters in strings are unequal. Number of characterss in words are unequal.)

How to extract the $m^{th}$ through $n^{th}$ words, so that e.g. $m=2, n=3$ should return:

{
"Hot Pink;53:09:44",
"Dark Cyan;19:06:42",
"Lime;54:11:55"
}  

UPDATE

Final solution was found for the task.
I like to share it here.

inlist = RandomChoice[
{"7270;Deep Pink;04:14:55;0027354",
 "2871;Dark Orchid;54:21:23;1182263",
 "4021;Silver;04:00:58;6940040",
 "3521;Dark Slate Gray;18:42:43;5828275"}, 
400000];  

delim = ";";
fromWord = 2;
numberOfWords = 2;  

from = 2 fromWord - 1;
to = 2 (fromWord + numberOfWords - 1) - 1;
outlist = List /@ StringJoin /@
      StringSplit[inlist, delim -> delim][[All, from ;; to]]; // Timing  

{0.92, Null}  

The honor goes to the very concerned in this task. Every detail of their conception was vital to the solution. Keep'n rocking.

share|improve this question
add comment

3 Answers

f[data_, from_, to_, sep_] := StringSplit[#, sep][[from ;; to]] & /@ data;
data = {"2894;Hot Pink;53:09:44;1449714", 
        "17456;Dark Cyan;19:06:42;6929227", 
        "5147;Lime;54:11:55;5247632"};

f[data, 2, 3, ";"]
(*
->{{"Hot Pink", "53:09:44"}, {"Dark Cyan", "19:06:42"}, {"Lime", "54:11:55"}}
*)
share|improve this answer
    
@NasserM.Abbasi Of course I can't be sure, but my interpretation comes from the use of the word throughin the OP's sentence Give a list of strings containing chars m'th "Word" through n'th "Word" in elements –  belisarius Dec 20 '12 at 11:41
2  
StringSplit is Listable. Try: f[data_, from_, to_, sep_] := StringSplit[data, sep][[All, from ;; to]] –  Mr.Wizard Dec 20 '12 at 11:55
    
Not quit what is expected. –  Hp Radojewski Schäfer Von Dec 21 '12 at 11:33
    
Will say, not a result with a 3 x 2 element list. It should be a list of 3 elements. The ";" sould be preserved. hp –  Hp Radojewski Schäfer Von Dec 21 '12 at 11:51
    
One could use Take[] instead of Part[]+Span[] of course... –  J. M. Apr 4 '13 at 14:51
show 2 more comments

Specific case for $m=2$ and $n=3$:

data = {"2894;Hot Pink;53:09:44;1449714",
        "17456;Dark Cyan;19:06:42;6929227",
        "5147;Lime;54:11:55;5247632"};

First@StringCases[#, 
   StartOfString ~~ __ ~~ ";" ~~ x__ ~~ ";" ~~ y__ ~~ ";" :> x <> ";" <> y] & /@ data
{"Hot Pink;53:09:44", "Dark Cyan;19:06:42", "Lime;54:11:55"}

More general version for any $m, n$:

{m, n} = {2, 3}

StringDrop[StringJoin@Drop[
    StringCases[#, Shortest[__ ~~ ";"], n], m - 1], -1] & /@ data
{"Hot Pink;53:09:44", "Dark Cyan;19:06:42", "Lime;54:11:55"}
share|improve this answer
    
Your result gives a 3 x 2 list. We need a list of 3 strings. Hot Pink;53:09:44 Dark Cyan;19:06:42 Lime;54:11:55 hp –  Hp Radojewski Schäfer Von Dec 21 '12 at 11:44
    
@HP Please see edit. Nasser: I hope you don't mind that I added the general case to your answer instead of creating a new one. It fits in nicely I think. I you feel otherwise, please don't hesitate to roll back. –  István Zachar Jan 5 '13 at 10:21
    
OK. . .Your function works well. . .It could not improve in timing compared to the algorithmic one shown below. –  Hp Radojewski Schäfer Von Jan 7 '13 at 7:56
    
Have an other look. It seems not to get the last words. . .If you do {m, n}={1, 4} –  Hp Radojewski Schäfer Von Jan 9 '13 at 17:01
add comment

A solution was developed. Building a program working on two Streams. One record by one record.

instr = OpenRead[infile];
outstr = OpenAppend[outfile];
azr=3; (* number of records to work on *)
abw=2; (* first word in record to extract *)
azw=2; (* number of words to extract *)
delim=";" (* separator char *)

Do[rean = Read[instr, "Record", NullWords -> True];
arean = rean <> delim;
pos = Flatten[StringPosition[arean, delim]];
fla = Flatten[{0, Drop[pos, {1, Length[pos], 2}]}];
extract = StringTake[arean, {fla[[abw]] + 1, fla[[abw + azw]] - 1}];
WriteString[outstr, extract, "\n"],
{i, azr}]; // Timing

It is a kind of ugly. Could not find a function solution.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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