0

So this is my code:

function PlusMinus() {
  str = str.replace(/([^\d\.](?!.*[^\d\.]))/, function(m, $1) {
    if ($1 == "-") return "";
    return $1 + "-";
  });
}

And it isn't working.

What I want to do, is to find the last occurrence of any character that is not a number (0-9) or a dot (.) and then if it is a "-", remove it, if it isn't replace the char with the char + "-".

Simply like a calculators -/+ button.

Examples:

"" -> "-"
"-" -> ""
"abc2-3" -> "abc23"
"a2-" -> "a2"
"s23.3" -> "s-23.3"
"4f" -> "4f-"

And yes, I've seen this: JavaScript RegExp: Can I get the last matched index or search backwards/RightToLeft? but I can't get it to work for chars in brackets

3
  • 1
    Provide some examples. Commented Oct 21, 2014 at 13:31
  • I guess you know that .replace() returns the new string instead of modifying the input one? That is to say, you need a left var: anyVar = str.replace(...);. Commented Oct 21, 2014 at 13:38
  • @sp00m Ik, but that wasn't the problem, edited though. Commented Oct 21, 2014 at 14:05

2 Answers 2

1

I would say something like this:

str.replace(/(?:^|.)(?=[\d.]*$)/,function(c) {
    return c == "-" ? "" : c+"-";
});

This will find a character such that all the characters after it are either numbers or a dot. Due to the greedy nature of quantifiers and the left-to-right processing of regexes, this will be the first such character found, which will be the last non-digit, non-dot character.

However, be sure to return or otherwise do something with the result! Otherwise you're just discarding it.

Sign up to request clarification or add additional context in comments.

7 Comments

I upvoted your answer, because I initially thought it was the same as my idea, but there are issues with your regular expression.
Well, with (/.(?=[\d.]+)$/ it's not working at all since the $ is outside the lookahead, but there are also other issues, since for exemple, in 333, the first 3 would be matched by your .. You also do not consider the case where '' must yield '-'.
@plalx Gotcha. Thanks, now fixed I believe.
Also, your code doesn't work?? Have you tried with the examples?
@Murplyx Ah, I see. I (wrongfully) assumed that there would actually be a number for your +/- to apply to. Edited. See tests
|
0
plusMinus(''); //'-'
plusMinus('-'); //''
plusMinus('abc2-3'); //'abc23'
plusMinus('a2-'); //'a2'
plusMinus('s23.3'); //s-23.3

function plusMinus(str) {
    return str.replace(/(^|[^\d\.])(?=[\d\.]*$)/, function ($0) {
        return $0 === '-'? '' : $0 + '-';
    });
}

I am just unsure about what to do with something like 33, because now it will return -33. Is this the desired behavior?

7 Comments

Yes it is, also, does $0 actually work??? Like, shouldn't the arguments be (match, $1, $2, $3...)
@Murplyx It's just the argument name. It could have been anything, but usually $0 is considered as full match so I chose this argument name. You could change it to match if you like it better.
As well, is there anyway to make this work for "abc123Infinity" -> "abc123-Infinity"
Is this: /(^|[^\d\.]|^Infinity)(?=[\d\.]|(Infinity)*$)/ correct then?
@Murplyx Will Infinity always be at the end? What would be the rule?
|

Your Answer

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