5
$\begingroup$

For example, I have a string "ahfiehfke$jfwfjejf0". Is there an elegant way to drop all characters after "$"? I know loop through and StringDrop till we hit the "$" would work, but I'm wondering if there is a better way.

$\endgroup$
4
  • 7
    $\begingroup$ First@StringSplit["ahfiehfke$jfw$fje$jf0", "$", 2] $\endgroup$ Apr 28 '15 at 16:09
  • $\begingroup$ @belisarius beat me to it. $\endgroup$
    – rcollyer
    Apr 28 '15 at 16:10
  • 2
    $\begingroup$ First[StringCases["ahfiehfke$jfwfjejf0", ___ ~~ "$", 1]] $\endgroup$
    – Coolwater
    Apr 28 '15 at 16:11
  • 1
    $\begingroup$ @Coolwater Your version fails when there are more than one $ in the string. The correct version: First[StringCases[str, Shortest[___] ~~ "$", 1]]. $\endgroup$ May 23 '15 at 6:08
10
$\begingroup$
StringTrim["ahfiehfke$jfwfjejf0", "$" ~~ __];

StringDelete["ahfiehfke$jfwfjejf0", "$" ~~ __]; (*V10.1*)
$\endgroup$
2
$\begingroup$

A bunch of regex methods:

str = "ahfiehfke$jfwfjejf0";

(* Coolwater *)
StringCases[str, RegularExpression["(?s).+?\\$", 1]][[1]]

StringReplace[str, RegularExpression["(?s)\\$.*"] :> "$", 1]

These use look-behind regexes:

StringReplace[str, RegularExpression["(?s)(?<=\\$).+"] :> "", 1]

StringTrim[str, RegularExpression["(?<=\\$).+"]]

(Thanks to Alexey for pointing out the need to properly handle newline characters.)

$\endgroup$
5
  • $\begingroup$ Note that both StringReplace solutions fail if the string contains a newline character \n after "$". You need to add the (?s) option to fix this. $\endgroup$ May 23 '15 at 2:43
  • $\begingroup$ Ah, of course. Thanks @Alexey. $\endgroup$
    – J. M.'s torpor
    May 23 '15 at 2:53
  • 1
    $\begingroup$ ... and the StringCases version fails if the string contains a newline character before $: it also needs the (?s) modifier. Only the StringTrim version works correctly without it because for StringTrim this modifier is already switched on internally. $\endgroup$ May 23 '15 at 5:53
  • 1
    $\begingroup$ The StringCases version also works incorrectly when there are more than one $ in the string. The correct version: StringCases[str, RegularExpression["(?s).+?\\$"], 1][[1]]. $\endgroup$ May 23 '15 at 6:03
  • $\begingroup$ Ah, that's what I get for trying to answer without a computer. :D Thanks again, @Alexey. $\endgroup$
    – J. M.'s torpor
    May 23 '15 at 6:04
1
$\begingroup$

Another method:

StringTake[str, StringPosition[str, "$", 1][[1, 1]]]

A comparison of performance of different methods which give identical results:

Needs["GeneralUtilities`"]
str = StringJoin@{Table["a", {1000}], Table["ahfieh\nfke$jfw\nfje$jf0", {1000}]};
Replace[Hold[{
     StringTrim[str, "$" ~~ __] <> "$",
     StringDelete[str, "$" ~~ __] <> "$",
     First@StringSplit[str, "$", 2] <> "$",
     First[StringCases[str, Shortest[___] ~~ "$", 1]],
 StringCases[str, RegularExpression["(?s).+?\\$"], 1][[1]],
     StringReplace[str, RegularExpression["(?s)\\$.*"] :> "$", 1],
     StringReplace[str, RegularExpression["(?s)(?<=\\$).+"] :> "", 1],
 StringTrim[str, RegularExpression["(?<=\\$).+"]],
     StringTake[str, StringPosition[str, "$", 1][[1, 1]]]
     }], x_ :> {HoldForm@x, AccurateTiming@x}, {2}] // 
  ReleaseHold // TableForm

table

It seems that the absolute winner is:

StringReplace[str, RegularExpression["(?s)\\$.*"] :> "$", 1]
$\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.