user3587624
user3587624

Reputation: 1471

Exclude the last character of a regex match

I have the following regex:

%(?:\\.|[^%\\ ])*%([,;\\\s]) 

That works great but obviously it also highlights the next character to the last %.

I was wondering how could I exclude it from the regex?

For instance, if I have:

The files under users\%username%\desktop\ are:

It will highlight %username%\ but I just want %username%. On the other hand, if I leave the regex like this:

%(?:\\.|[^%\\ ])*%

...then it will match this pattern that I don't want to:

%example1%example2%example3

Any idea how to exclude the last character in the match through a regex?

Upvotes: 10

Views: 19624

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626689

You can use a more effecient regex than you are currently using. When alternation is used together with a quantifier, there is unnecessary backtracking involved.

If the strings you have are short, it is OK to use. However, if they can be a bit longer, you may need to "unroll" the expression.

Here is how it is done:

%[^"\\%]*(?:\\.[^"\\%]*)*%

Regex breakdown:

  • % - initial percentage sign
  • [^"\\%]* - start of the unrolled pattern: 0 or more characters other than a double quote, backslash and percentage sign
  • (?:\\.[^"\\%]*)* - 0 or more sequences of...
    • \\. - a literal backslash followed by any character other than a newline
    • [^"\\%]* - 0 or more characters other than a double quote, backslash and percentage sign
  • % - trailing percentage sign

See this demo - 6 steps vs. 30 steps with your %(?:\\.|[^" %\d\\])*%.

Upvotes: 4

vks
vks

Reputation: 67968

%(?:\\.|[^%\\ ])*%(?=[,;\\\s])

                   ^^

Use a lookahead.What you need here is 0 width assertion which does not capture anything.

Upvotes: 5

Related Questions