5
$\begingroup$

Is it possible to extract the sign using Regular Expression ?

For example {"Today+100","Yesterday-200"}. And I need {"Today",100,"Yesterday",-200}.

Currently, I use Regular Expression to get the sign and number. Then combine them. But I reckon there should be a better method.

Thanks

$\endgroup$
10
$\begingroup$
lst = {"Today+100", "Yesterday-200"};

StringSplit

StringSplit[lst, RegularExpression["([+-]\\d+)"] :> ToExpression@"$1"]

{{"Today", 100}, {"Yesterday", -200}}

StringSplit[lst, n : NumberString :> ToExpression@n]

{{"Today", 100}, {"Yesterday", -200}}

StringReplace

List @@@ StringReplace[lst, RegularExpression["([+-]\\d+)"] :> ToExpression@"$1"]

List @@@ StringReplace[lst, n : NumberString :> ToExpression@n]

Sequence @@@ StringReplace[lst,
   RegularExpression["(\\w+)([+-]\\d+)"] :> {"$1", ToExpression@"$2"}]

Sequence @@@ StringReplace[lst, 
  w : WordCharacter .. ~~ n : NumberString :> {w, ToExpression @ n}]

all give

{{"Today", 100}, {"Yesterday", -200}}

Note: My original answer used the regex substring [\\+\\-]. I learned from @user1066's comment and answer that it can be replaced with much nicer [+-].

$\endgroup$
3
  • 1
    $\begingroup$ I voted for @kglr, who is amazing. Could you explain what the ToExpression does (in the first two) for us lesser mortals? $\endgroup$ – Mike Colacino Mar 17 '20 at 15:54
  • $\begingroup$ @user1066, very good point. It just did not occur to me:) I suggest you post that (much cleaner) form as an answer. $\endgroup$ – kglr Mar 17 '20 at 17:35
  • 2
    $\begingroup$ @MikeColacino, without ToExpression we get {{"Today", "+100"}, {"Yesterday", "-200"}}. ToExpression turns "+100" into 100 and "-200" into -200. $\endgroup$ – kglr Mar 17 '20 at 17:38
4
$\begingroup$

Maybe this will help:

StringCases[#, 
    WordCharacter .. | (_ ~~ DigitCharacter ..)] & /@ {"Today+100", 
   "Yesterday-200"} // Flatten
(* {"Today", "+100", "Yesterday", "-200"} *)
$\endgroup$
3
$\begingroup$

A slight modification of @kglr's first method, (the one containing the neat use of ToExpression):

StringSplit[lst, 
  RegularExpression["[+-]\d{3}"]:> ToExpression["$0"]]

{{Today, 100}, {Yesterday, -200}}

(Originally posted as a comment)

$\endgroup$
1
  • $\begingroup$ In addition, using StringCases with positive look-ahead (see this answer by Alexey Popkov: StringCases[lst, RegularExpression["(^.+)(?=[+-])([+-]\d{3})"]:> {"$1", ToExpression["$2"]}] $\endgroup$ – user1066 Mar 18 '20 at 16:56
2
$\begingroup$

I think OP wants to get rid of the "+" in front of the positive ones, which makes it a little more complicated.

ss[s_ /; StringMatchQ[s, __ ~~ "-" ~~ __]] := (str = StringSplit[s, "-"]; {str[[1]], "-" <> str[[2]]});
ss[s_ /; StringMatchQ[s, __ ~~ "+" ~~ __]] := StringSplit[s, "+"]
ss /@ {"Today+100", "Tomorrow-200"} // Flatten

Of course everything is a string here, which might or might not matter to OP.

$\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.