1

I thought this would be a common and easy thing to do, but so far I've been unable to find an answer by Googling.

How would I regex match a substring only if it is not immediately preceded by a specific string?

In this case I want to match " (a space followed by a quotation mark) but only if it's not preceded by , (a comma). I've tried a few different things. Currently (?!,) " is as close as I've gotten, but the negative lookahead doesn't seem to be working as I expect.

Some examples of what I want:

Laura said "What have you done?"            - 1 match
Laura said, "What have you done?"           - 0 matches (there's a comma)
"Come with me," David said.                 - 0 matches (no space before the ")
Michael said "Throw it!" Jessica replied, "I'd rather not..." Shia shouted "Just do it!"
- 2 matches

This is in Notepad++. What am I doing wrong?

2
  • If you have a string like a,<2 or 3 spaces>", should anything be matched here? Commented Jan 3, 2018 at 7:28
  • 1
    @WiktorStribiżew Thanks for fixing my formatting, I could not figure out how to do that for the life of me. I think yes, because double or triple spacing is a separate issue I'd have to fix. But either way I can take either of the current answers and modify them to suit my needs. So all good ;) Commented Jan 3, 2018 at 11:58

2 Answers 2

2

You can use double assertions to apply two conditions.

(?<= )(?<!, )"

(?<= ) -> Positive lookbehind assertion which asserts that the character going to be matched must be preceded by a space character.

(?<!, ) -> Negative lookbehind which asserts that the character going to be matched must not be preceded by a ,<space> characters.

" -> match the double quotes only if both conditions gets satisfied.

OR

(?<=[^,] )"|(?<=^ )"

(?<=[^,] )" -> positive lookbehind which asserts that the double quotes must be preceeded by

  • any char but not of , [^,]
  • followed by a space character

And note that this regex won't match a double quotes preceded by a space char exists at the line start like this *. In-order to match the quotes exists at the line start, we have to use another condition like

(?<=^ )" matches the quotes which was preceded by,

  • ^ start of the line.
  • <space> character

On ORing these two conditions with | OR operator, you can achieve the expected results.

DEMO

If you want to match also the preceding space then remove the space from lookahead assertions.

(?<!,) "

(?<!,) asserts that the chars going to be matched won't be preceded by ,.

DEMO

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

3 Comments

That does indeed appear to work (well, it matches only the quotation mark instead of including the space, but for my purposes that doesn't actually matter). I'm now trying to decipher what's going on here (thank goodness for regex101) but it'd be great if you could add your own explanation :)
@Clonkex if you want to include the space then remove the space from lookahead assertions. (?<!,) "
Fantastic answer with great explanations! I'll have some more questions later I'm sure. When I've tested it properly I'll give you the accepted mark :)
1

This seemed to work for me, tested in Notepad++:

[^,]\K "

9 Comments

Yep that works. It's also blatantly obvious what's happening, so I'm a fan. I feel dumb for not thinking of it this way. However this method also captures the character immediately preceding the space. Even though it doesn't matter for my particular use case, could you edit your post with a way to avoid that, if possible? For future reference and all that :)
Err actually, looks like @AvinashRaj has got it taken care of.
\Kcan be used to keep the left of \K out of match for example [^,]\K "
however it will not match if ` "` is at the beginning of the line, if it's the case (?:^|[^,])\K "
He probably does deserve credit especially considering how much effort he put into the detailed explanations, however the accepted answer should always be the answer that was most useful to the OP, and in this case yours is.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.