简体   繁体   中英

Match only @ and not @@ without negative lookbehind

Using JavaScript, I need a regex that matches any instance of @{this-format} in any string. My original regex was the following:

@{[a-z-]*}

However, I also need a way to "escape" those instances. I want it so that if you add an extra @, the match gets escaped, like @@{this}.

I originally used a negative lookbehind:

(?<!@)@{[a-z-]*}

And that would work just fine, except... lookbehinds are an ECMAScript2018 feature, only supported by Chrome.

I read some people suggesting the usage of a negated character set. So my little regex became this:

(?:^|[^@])@{[a-z-]*}

...which would have worked just as well, except it doesn't work if you put two of these together: @{foo}@{bar}

So, anyone knows how can I achieve this? Remember that these conditions need to be met:

  • Find @{this} anywhere in a string
  • Be able to escape like @@{this}
  • Be able to put multiple adjacent, like @{these}@{two}
  • Lookbehinds must not be used

If you include @@ in your regex pattern as an alternate match option, it will consume the @@ instead of allowing a match on the subsequent bracketed entity. Like this:

@@|(@{[az-]*})

You can then evaluate the inner match object in javascript. Here is a jsfiddle to demonstrate, using the following code.

var targetText = '@{foo} in a @{bar} for a @@{foo} and @{foo}@{bar} things.'
var reg = /@@|(@{[a-z-]*})/g;
var result;
while((result = reg.exec(targetText)) !== null) {
        if (result[1] !== undefined) {
        alert(result[1]);
    }
}

You could use (?:^|[^@])@ to match the start of the pattern, and capture the following @{<sometext>} in a group. Since you don't want the initial (possible) [^@] to be in the result, you'll have to iterate over the matches manually and extract the group that contains the substring you want. For example:

 function test(str) { const re = /(?=(?:^|[^@])(@{[az-]*}))./g; let match; const matches = []; while (match = re.exec(str)) { matches.push(match[1]); // extract the captured group } return matches; } console.log(test('@@{this}')) console.log(test('@{these}@{two}'))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM