# Isolating string characters

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 :/.

• 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}] Commented Aug 23, 2014 at 19:31

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"}} *)

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"}} *)

• +1 - The first answer I almost understand. You could save 2 characters and a couple of nanoseconds by replacing StringJoin with ToString :)
– eldo
Commented Aug 23, 2014 at 19:03
• @eldo, thank you. ToString makes sense; but it gives extra commas to clean-up.
– kglr
Commented Aug 23, 2014 at 19:06
• @eldo, thanks again. Fixed the comma issue; but it took more than the two extra characters saved with ToString:)
– kglr
Commented Aug 23, 2014 at 19:16

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"}}