6
$\begingroup$

I have the following string:

 string=  {{"D(2.00225050736308e-15*A01 - 0.0201549279513608) = \
    0.0820842279730734 + 0.08923448712*delay(A35", 
      " 17) + 0.08669543966*delay(A88", 
      " 20) + 1.98960079968027e-16*A57 - 0.3146216003*erf(delay(A01", 
      " 2)) - 0.3157150548*erf(sin(0.00541313376373593*cos(0.\
    129564165001876 + 2.22963213427193e-15*A57 - \
    gauss(0.00170510841714258 + 1.87338787507e-15*A51)) + delay(A27", 
      " 24) + gauss(gauss(0.00170510841714258 + 1.87338787507e-15*A51)) - \
    2.17740845675611e-15*A81*cos(0.129564165001876 + \
    2.22963213427193e-15*A57 - gauss(0.00170510841714258 + \
    1.87338787507e-15*A51))))"}}

I want to isolate all characters within the brackets of the delay part e.g. delay(A27, 24). In other words I want the characters A24 and 24. My best bet was to go with

StringCases[string,"delay("~~__~~")"]

in order to get all String between the brackets, but this does not work. Still a little bit confused about using string patterns :/.

$\endgroup$
  • 1
    $\begingroup$ As @belisarius alluded to, by default __ and ___ are "greedy" in string patterns -- meaning they will yield the longest possible match. By contrast, in nonstring patterns the default behavior is the opposite. Compare: StringReplace["abcde", x__ ~~ y__ :> x] and Replace[{a, b, c, d, e}, {x__, y__} :> {x}] $\endgroup$ – mfvonh Aug 23 '14 at 19:31
11
$\begingroup$

Shortest[] is the easiest way to stop the greedy pattern matching algorithm:

StringCases[StringJoin[string], Shortest["delay(" ~~ x__ ~~ " " ~~ y__ ~~ ")"] -> {x, y}]
(* {{"A35", "17"}, {"A88", "20"}, {"A01", "2"}, {"A27", "24"}} *)

Edit:

As @Öskå showed in his answer, it can be done without using Shortest[] too. Here's another way that doesn't need to mess with the string lengths:

f = StringFreeQ[#, ")"] &;
StringCases[StringJoin[string], "delay(" ~~ x__?f ~~ " " ~~ y__?f ~~ ")" -> {x, y}]
(* {{"A35", "17"}, {"A88", "20"}, {"A01", "2"}, {"A27", "24"}} *)
$\endgroup$
2
$\begingroup$

Just a solution without Shortest because I simply didn't know about it:

StringReplace[#, ")" -> ""] & /@ 
  StringCases[StringJoin[string], "delay(" ~~ x__ ~~ " " ~~ y__ ~~ ")" /; 
      (StringLength@x < 5 && StringLength@y < 5) :> {x, y}]
{{"A35", "17"}, {"A88", "20"}, {"A01", "2"}, {"A27", "24"}}
$\endgroup$
2
$\begingroup$
StringCases[StringJoin[string], "delay(" ~~ x : Except[")"] .. ~~ ")" :> StringSplit[x]]
(* {{"A35","17"},{"A88","20"},{"A01","2"},{"A27","24"}} *)

or,

StringCases[ToString[string], "delay(" ~~ x:Except[")"] .. ~~ ")" :> 
                                 StringSplit[x, ","]]       (*thanks: eldo *)
(* {{"A35", "  17"}, {"A88", "  20"}, {"A01", "  2"}, {"A27", "  24"}} *)
$\endgroup$
  • $\begingroup$ +1 - The first answer I almost understand. You could save 2 characters and a couple of nanoseconds by replacing StringJoin with ToString :) $\endgroup$ – eldo Aug 23 '14 at 19:03
  • $\begingroup$ @eldo, thank you. ToString makes sense; but it gives extra commas to clean-up. $\endgroup$ – kglr Aug 23 '14 at 19:06
  • $\begingroup$ @eldo, thanks again. Fixed the comma issue; but it took more than the two extra characters saved with ToString:) $\endgroup$ – kglr Aug 23 '14 at 19:16

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.