0

I have a regex like this:

str.replace(/([^a-zA-Z])e([^a-zA-Z])/g, "$12.718281828459045$2")

The regex isn't doing what I want, and I don't know why.

So what I want to to do, is to replace all "e"'s in a string that's not connected to any A-z letter with "2.718281828459045", what's wrong in my regex?

"2e" -> "2e", should be: "22.718281828459045"
"2e2" -> "22.7182818284590452", working
"2*e*e*2" -> "2*2.718281828459045*e*2", should be "2*2.718281828459045*2.718281828459045*2"
4
  • 2e will not work as there is nothing after e. Commented Oct 18, 2014 at 12:27
  • @vks How about "2*e*e*2"? Commented Oct 18, 2014 at 12:37
  • You can solve this with a negative lookahead. Shown working here: regex101.com/r/wQ1oW3/2 Commented Oct 18, 2014 at 12:38
  • @Alxandr post an answer? Commented Oct 18, 2014 at 12:42

5 Answers 5

1

The problem here is that the first one does not match because there is nothing after the e, thus it has to check for an e followed by something that isn't a letter or end of input. However, the third example doesn't work because in 2*e*e*2 the first match is *e*, thus both * are "consumed", so what's left of the string is only e*2. This obviously doesn't fix the problem.

What can be used in stead is a negative lookahead. They are written as a(?!b) in regex and (in this case) means an a not followed by a b. So we make the regex into ([^a-zA-Z])e(?![a-zA-Z). However, this still does not match the simple string e, because there is nothing in front of it. In something that's not JavaScript we could use a negative lookbehind, though js doesn't support this, so rather just change it to (^|[^a-zA-Z])e(?![a-zA-Z]).

The meaning is: Find any e that is at the beginning of the string, or after something that's not a-z or A-Z, and is not followed by an a-z or A-Z.

Here is working demo: http://regex101.com/r/wQ1oW3/3 (note, I replaced with <input> though, because it's simpler to see that the replacing is right.)

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

5 Comments

But this one takes less space than a positive, does that make any difference?
So this should be (^|[^a-zA-Z])e(?![a-zA-Z]|$) instead of (^|[^a-zA-Z])e(?![a-zA-Z])?
No, the negative lookahead deals with end of string it seems. You can see that here: regex101.com/r/wQ1oW3/5
So /(^|[^a-zA-Z])e(?![a-zA-Z])/g === /(^|[^a-zA-Z])e(?=[^a-zA-Z]|$)/g
Yeah, it would seem so. There's more than one way to Rome.
0

The second set of parentheses consumes that part of the string for the regex. What that means is that the remaining string e*2 does not match because that e is not preceded by the non-alphanumeric character. You can use a lookahead instead which does not consume.

"2*e*e*2".replace(/([^a-zA-Z])e(?=[^a-zA-Z])/g, "$12.718281828459045")

1 Comment

("2*e").replace(/([^a-zA-Z])e(?=[^a-zA-Z])/g, "$12.718281828459045") -> "2*e", should be "2*2.718281828459045"
0

Try this regex -

Regex   - ([^a-zA-Z])?(?:e(?:.*e)?)([^a-zA-Z])?
Replace - $12.718281828459045$2

DEMO

1 Comment

("e*e").replace(/([^a-zA-Z])?(?:e(?:.*e)?)([^a-zA-Z])?/g, "$12.718281828459045$2") -> "2.718281828459045", should be "2.718281828459045*2.718281828459045"
0

How about:

find:    /(^|[^a-zA-Z])e(?=[^a-zA-Z]|$)/g
replace: $12.718281828459045

.

str.replace(/(^|[^a-zA-Z])e(?=[^a-zA-Z]|$)/g, "$12.718281828459045")

13 Comments

e*e -> ${1}2.718281828459045${1}2.718281828459045, not working?
@Murplyx: I've forgotten the g (global) modifier. see my edit
Is there any difference between this: regex101.com/r/wQ1oW3/2 as Alxandr posted and yours?
Not really, he uses negative look ahead and I use positive lookahead. I haven't seen his answer before I posted mine.
@Murplyx: TThe one you understand the best. It's just a question of taste
|
0

try with /([^a-zA-Z])?e(?![a-zA-Z])/g And '$12.718281828459045' for replacement.

Using negative look ahead, and an optional previous alpha character as there is no lookbehind in JS (that I know of).

Comments

Your Answer

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