0

Why is the expression

(?<=\s)\d(?=\s)

not the same as the expression

(?<!\S)\d(?!\S)

?

zwithouta
  • 808
  • 5
  • 13

2 Answers2

2

One difference is that positive lookbehind and lookahead require those characters being looked for to exist, whereas negative lookaround does not. For example

1 2

will have 2 matches by

(?<!\S)\d(?!\S)

but no matches by

(?<=\s)\d(?=\s)

https://regex101.com/r/tjYc1o/1

(?=\s) requires the digit to be followed by a space character, so the digit will not be matched if the digit is at the end of the string, but if (?!\S) was used instead, the negative lookahead would pass, because the digit at the end of the string is not followed by a non-whitespace character.

CertainPerformance
  • 260,466
  • 31
  • 181
  • 209
  • Thanks a lot! Given the string "1 2" I thought that the end of the line is seen as 'something else than a whitespace' and that therefore (?!\S) should be False. – zwithouta Dec 19 '18 at 22:38
  • This can't be generalized as true. Positive assertions don't necessarily require a character to exist. Neither positive nor negative has a property like that... –  Dec 19 '18 at 22:51
  • 1
    @sln Of course, if OP was using something that didn't consume characters like `\b` / `\B` or another lookahead, that'd be true, but OP is using `\s` and `\S`, which matches a character - so, the positive lookarounds require the characters being looked for to exist, while the negative lookarounds don't. (if no characters are being looked for at all, that's a separate category) – CertainPerformance Dec 19 '18 at 23:02
  • Not true still. The OP's negative assertions _do_ require the character exists, it must be a whitespace. So, you see, it isn't the assertion by itself that is the difference. –  Dec 19 '18 at 23:11
  • @sln What do you mean? The negative lookarounds *don't* require the character to exist - eg, with negative lookbehind and lookahead only, a string containing `1` and nothing else is matched https://regex101.com/r/tjYc1o/2 (no whitespaces) Switch the `\S`s in the lookarounds for `\s` and the same thing occurs - the digit is still matched, because the lookarounds fail – CertainPerformance Dec 19 '18 at 23:15
  • Do, I said do `OP's negative assertions do require the character exists` –  Dec 19 '18 at 23:16
  • @sln But negative lookaround does not require any character to exist. For example, `(? – CertainPerformance Dec 19 '18 at 23:19
  • So, then it's not the inherent property of negative assertions that control any requirements that a character exist. No, the assertion doesn't have that ability, it's what's in the assertion that controls the outcome. –  Dec 19 '18 at 23:24
  • A specific outcome like whitespace will satisfy both `(? –  Dec 19 '18 at 23:26
  • @sln I don't understand the problem you're having with it. The answer, as in the question, is about the situation when positive or negative lookaround contains a character. As you can see in the first comment, I'm perfectly aware that there can be lookarounds that don't match characters, but the question was not asking about that, nor did my answer say anything about that. In the case that the lookarounds are matching characters, which is what the question is about and is what I answered, positive lookarounds require that some characters being looked for exist, while negative lookarounds don't – CertainPerformance Dec 19 '18 at 23:39
  • We're going in a loop here, outside of BOS/EOS, this `(?!\S)` requires that a character exist, so does `(?=\s)`. So, it has nothing to do with negative/positive assertions. –  Dec 19 '18 at 23:42
  • So as long as not at the end of a string positive as well as negative lookaheads (using \s) decide on the basis of an existing character if they pass or fail. But at the last position of a string negative lookaheads of this kind always pass, whereas positive lookaheads of this kind always fail. Did I get it right now? – zwithouta Dec 20 '18 at 00:27
0
 #Why is the expression
 (?<= \s )
 \d
 (?= \s )

 #not the same as the expression
 (?<! \S )
 \d
 (?! \S )

When you use a negative assertion on a negated class it will also match
at the BOS and EOS positions, whereas the positive assertion will not.

  • Has the negative assertion really to be used on a negated character class for your statement to be true? (? – zwithouta Dec 20 '18 at 00:36
  • @zwithouta - This is not an easy topic for beginners to understand. The little regex _magic_ comes from a _negated class_ wrapped inside a negative assertion. It's not _just_ the assertion. This is about matching something in mid-string, like delimiters. A positive class is too limited to define what you don't want vs. what you do, so use a negated class to define specific things _you want_. For example `(?![^abc])` where a or b or c is a delimiter (in text) that you require, OR the EOS/BOS. Remember that `(?!\s)` is really `(?!(?=\s))` –  Dec 20 '18 at 02:16