2

Is it possible to construct a regular expression for this? If so, I'd appreciate if someone shows how.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • 2
    Should it match `'` if it's preceded by an even number of \ symbols? (I.e. \ is frequently used to start escape sequences. Often, in such a case, \\ is the escape sequence for a literal \. And so, an even number of such means that the \ immediately before the `'` isn't starting an escape sequence - it's completing one) – Damien_The_Unbeliever Jul 09 '13 at 10:26
  • @Damien_The_Unbeliever: good point! It would be nice for the sake of completeness to account for this, but I don't think it's neccessary in my case. – Violet Giraffe Jul 09 '13 at 10:28
  • It would be much easier to match the exact opposite: all characters except apostrophes, yet including escaped apostrophes. Would that be helpful? – Bergi Jul 09 '13 at 11:08

2 Answers2

4

Use this regular expression:

(?<!\\)'

It means match all apostrophe chars not preceeded by a backslash (the backslash is escaped itself because it is a special char for regexps)

Teejay
  • 7,210
  • 10
  • 45
  • 76
  • What if the string is `"\\'"`? – Tim Pietzcker Jul 09 '13 at 10:30
  • Eep, indeed. Sorry for the broken attempt (and more fiddling with broken comment syntax than the regex -.-) – Joey Jul 09 '13 at 10:31
  • @TimPietzcker: as you pointed out, my regexp will not work *as you intend* in that case. I only replied to the OP which was asking about a **regexp to match** `'` **not preceeded by** `\ `, I actually wasn't trying to implement a parser on-the-fly... – Teejay Jul 09 '13 at 10:43
  • 1
    Sure, your answer is technically correct (for the question as it was originally asked), but when somebody has an [XY problem](http://meta.stackexchange.com/q/66377/136323), I find it nicer to actually solve `X` than `Y` :) – Tim Pietzcker Jul 09 '13 at 10:46
  • @TimPietzcker You are right, but I'm not (and neither are you) aware of what OP is actually trying to achieve. – Teejay Jul 09 '13 at 10:50
  • I thought I did (because @VioletGiraffe said in a comment the goal was to escape apostrophes correctly. Apparently it isn't). – Tim Pietzcker Jul 09 '13 at 11:18
3

If you are using the .NET regex engine or another engine that can handle indefinite-length lookbehind assertions, then use

(?<=(?<!\\)(?:\\\\)*)'

That makes sure that there is an even number of backslashes before the apostrophe.

Explanation:

(?<=        # Assert that the following regex matches before the current position:
 (?<!\\)    # No backslash before...
 (?:\\\\)*  # ... an even number of backslashes.
)           # (End of lookbehind assertion)
'           # Match an apostrophe.

If your regex engine can't handle that, you'll need to make the (even number of) backslashes part of the match and account for them later:

(?<!\\)((?:\\\\)*)'

Now $1 (or \1) will contain the matched backslashes, so you can replace the result by \1\\' or $1\\', depending on the details of the QRegExp implementation.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561