3
$\begingroup$

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.

$\endgroup$
0
6
$\begingroup$
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"}}
*)
$\endgroup$
7
  • $\begingroup$ @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 $\endgroup$ Dec 20 '12 at 11:41
  • 2
    $\begingroup$ StringSplit is Listable. Try: f[data_, from_, to_, sep_] := StringSplit[data, sep][[All, from ;; to]] $\endgroup$
    – Mr.Wizard
    Dec 20 '12 at 11:55
  • $\begingroup$ Not quit what is expected. $\endgroup$ Dec 21 '12 at 11:33
  • $\begingroup$ 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 $\endgroup$ Dec 21 '12 at 11:51
  • $\begingroup$ One could use Take[] instead of Part[]+Span[] of course... $\endgroup$
    – J. M.'s torpor
    Apr 4 '13 at 14:51
4
$\begingroup$

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"}
$\endgroup$
4
  • $\begingroup$ 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 $\endgroup$ Dec 21 '12 at 11:44
  • $\begingroup$ @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. $\endgroup$ Jan 5 '13 at 10:21
  • $\begingroup$ OK. . .Your function works well. . .It could not improve in timing compared to the algorithmic one shown below. $\endgroup$ Jan 7 '13 at 7:56
  • $\begingroup$ Have an other look. It seems not to get the last words. . .If you do {m, n}={1, 4} $\endgroup$ Jan 9 '13 at 17:01
1
$\begingroup$

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.

$\endgroup$

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.