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.
$\begingroup$
$\endgroup$
$\begingroup$
$\endgroup$
StringTrim["ahfiehfke$jfwfjejf0", "$" ~~ __];
StringDelete["ahfiehfke$jfwfjejf0", "$" ~~ __]; (*V10.1*)
$\begingroup$
$\endgroup$
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.)
-
$\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$ – Alexey Popkov May 23 '15 at 2:43 -
-
1$\begingroup$ ... and the
StringCases
version fails if the string contains a newline character before$
: it also needs the(?s)
modifier. Only theStringTrim
version works correctly without it because forStringTrim
this modifier is already switched on internally. $\endgroup$ – Alexey Popkov 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$ – Alexey Popkov 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 ennui♦ May 23 '15 at 6:04
$\begingroup$
$\endgroup$
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
It seems that the absolute winner is:
StringReplace[str, RegularExpression["(?s)\\$.*"] :> "$", 1]
First@StringSplit["ahfiehfke$jfw$fje$jf0", "$", 2]
$\endgroup$ – Dr. belisarius Apr 28 '15 at 16:09First[StringCases["ahfiehfke$jfwfjejf0", ___ ~~ "$", 1]]
$\endgroup$ – Coolwater Apr 28 '15 at 16:11$
in the string. The correct version:First[StringCases[str, Shortest[___] ~~ "$", 1]]
. $\endgroup$ – Alexey Popkov May 23 '15 at 6:08