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
  • 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, 2014 at 19:31

3 Answers 3

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$
0
3
$\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$
3
  • $\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, 2014 at 19:03
  • $\begingroup$ @eldo, thank you. ToString makes sense; but it gives extra commas to clean-up. $\endgroup$
    – kglr
    Aug 23, 2014 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, 2014 at 19:16
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$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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