1

I know that a lot of people have posted a similar question but with the g flag, none of the "hacks" seem to work for me properly (meaning they don't work most of the time). Yes I want the g flag The regex I've made is:

\~\![A-Za-z]+\ start(?:(?:(?:\(|,)\ ?[\w]+)*?\))\:\{([\S\s]+?)(?:(?<!\\)\}\:end)

This works fine when negative look-behind is supported. But when I do it in JavaScript. It doesn't support negative look behind. Here's the part where the problem lies:

(?:(?<!\\)\}\:end)

What it should match:

\}:end    <- Not this
}:end     <- This
foo}:end  <- This

I've tried:

Community
  • 1
  • 1
Downgoat
  • 13,771
  • 5
  • 46
  • 69
  • 1
    What's up with `[\S\s]`? As far as I know, it means the same thing as `.`. – John Bollinger May 02 '15 at 18:27
  • `This works fine in PCRE` - how this is relevant to javascript ? PCRE is far more powerfull, what's your question ? You might try to google some PCRE.js porting attemps, like https://github.com/mscdex/node-pcre . That's the simplest thing to do if you want a richer syntax in your regexps. – c69 May 02 '15 at 18:29
  • @JohnBollinger That's so it can match newlines. – Downgoat May 02 '15 at 18:29
  • @John `[\S\s]` is not the same as `.`, because it also matches `\n`. – Lucas Trzesniewski May 02 '15 at 18:30
  • To avoid relying on negative lookbehind, you need to modify the *preceding* part of the regex. – John Bollinger May 02 '15 at 18:31
  • @c69 I'm not so open to the idea of adding a whole library for a single negative lookbehind – Downgoat May 02 '15 at 18:32
  • I just wrote an [answer to a similar question](https://stackoverflow.com/questions/35142364/regex-negative-lookbehind-not-valid-in-javascript/35143111#35143111 "regex Negative Lookbehind not valid in javascript") with full descriptions of how to match and replace with both positive and negative lookbehinds, **including support for global modifiers**. Take a look. – Adam Katz Feb 09 '16 at 01:58

2 Answers2

2

Instead using lookbehind you can use lookahead

e.g.

abcdefg;}hijklmn#}

to get

$1 = `abcdefg;}hijklmn`
$2 = `#}`

using lookbehind approach you can do

(.*)(?<!#})(#})

see: DEMO (lookbehind approach)

which here prevent a duplication of #} by using negative lookbehind.

On the other hand, lookahead approach is also possible by "spawning lookahead",

let's consider our example text

abcdefg;}hijklmn#}

become

%a%b%c%d%e%f%g%;%}%h%i%j%k%l%m%n%#}

here %s represent to lookahead.

How we can spawn lookahead like that?

Let's consider lookahead approach regex for our example text

((?:(?!#}).)*)(#})

see: DEMO (lookahead approach)

A trick here is spawning lookahead together with . where the regex ((?:(?!#}).)*) can be expanded to

((?!#}).(?!#}).(?!#}).(?!#}).(?!#}).(?!#}).) and so on

that means it will check for every letters to guarantee you that there is no #} in (.*).

Thus, if apply this strategy to your regex you will get

\~\![A-Za-z]+\ start(?:(?:(?:\(|,)\ ?[\w]+)*?\))\:\{((?:(?!\}\:end\n)[\S\s])+)(?:\}\:end)

see: DEMO

fronthem
  • 4,011
  • 8
  • 34
  • 55
1
\~\![A-Za-z]+\ start(?:(?:(?:\(|,)\ ?[\w]+)*?\))\:\{([\S\s]+?)(?:[^\\]\}\:end)

Try this, see the demo:

https://regex101.com/r/uE3cC4/17

Downgoat
  • 13,771
  • 5
  • 46
  • 69
vks
  • 67,027
  • 10
  • 91
  • 124
  • 1
    Nice! But what if I wanted to change it so: `abc}:end` would not be selected. `(?:[^a]{1,1}[^b]{1,1}[^c]{1,1})` doesn't seem to work – Downgoat May 02 '15 at 18:38