And ideally, I want to allow spaces between, say and e and the minus:
(?<!(^|[eE]))\s*-
(the reason \s* is outside the lookbehind is that negative lookbehinds need be a fixed length, which \s* is not)
the logic here makes sense to me: match \s*- unless it is preceded by ^, e or E
this is intended as part of a larger pattern meant to purge e.g. thousands separators from a number string:
[^\d,.\-+eE]|(?<!(^|[eE]))\s*[+\-]|[eE](?!\s*[+\-]?\s*\d+$)|[.,](?=.*[.,])
What this does is (in order), it matches
- everything that isn't a number, a comma, a dot, a minus, a plus or an E
- all pluses and minuses that aren't at the beginning of the string and that don't follow
eorE - all
eandEthat aren't followed by at least one digit with potentially a plus or minus between the E and the digit - all dots and commas except the last dot or comma
i.e. everything matched by this pattern can be replaced with an empty string.
Now let's try that in Java:
private static final Pattern ALL_NON_NUMERICS_EXCEPT_LEADING_MINUS_AND_E_AND_LAST_DOT_OR_COMMA = Pattern.compile("[^\d,.\-+eE]|(?<!(^|[eE]))\s*[+\-]|[eE](?!\s*[+\\-]?\s*\d+$)|[.,](?=.*[.,])");
and
var intermediate = ALL_NON_NUMERICS_EXCEPT_LEADING_MINUS_AND_E_AND_LAST_DOT_OR_COMMA
.matcher("3 e -9")
.replaceAll("");
But as you can see here, the result of that is 3e9 and not 3e-9 as it should.
So I pasted just the (?<!(^|[eE]))\s*- pattern to regex101 and turns out that the lookbehind is "not fixed", after all.
I do think it's possible this results in a mis-compilation of the pattern.
So how do I actually DO this?