Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #197873

Re: re.sub(r'((?<=\A)|(?<=,))(?=,|\Z)', 'NA', ',1,,,two,3,,,') how does it work?

Path csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail
From ram@zedat.fu-berlin.de (Stefan Ram)
Newsgroups comp.lang.python
Subject Re: re.sub(r'((?<=\A)|(?<=,))(?=,|\Z)', 'NA', ',1,,,two,3,,,') how does it work?
Date 9 Aug 2026 11:24:12 GMT
Organization Stefan Ram
Lines 111
Expires 1 Jun 2027 11:59:58 GMT
Message-ID <advances-20260809120133@ram.dialup.fu-berlin.de> (permalink)
References <1158h6s$1ts3e$1@dont-email.me>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8
Content-Transfer-Encoding 8bit
X-Trace news.uni-berlin.de WzcqaJPW9FwPdVC5s9TEYQIHfZlw1OOb8I0fHiD2zZCFJ2
Cancel-Lock sha1:eytTZhsitF8w6MXYvtmeKdU+4O4= sha256:z+1aGHJgO6zTFB/MuZjRNJ+gTPVPvMh5xMfz7V/EPjw=
X-Copyright (C) Copyright 2026 Stefan Ram. All rights reserved. Distribution through any means other than regular usenet channels is forbidden. It is forbidden to publish this article in the Web, to change URIs of this article into links, and to transfer the body without this notice, but quotations of parts in other Usenet posts are allowed.
X-No-Archive Yes
Archive no
X-No-Archive-Readme "X-No-Archive" is set, because this prevents some services to mirror the article in the web. But the article may be kept on a Usenet archive server with only NNTP access.
X-No-Html yes
Content-Language en
Xref csiph.com comp.lang.python:197873

Show key headers only | View raw


Veek M <veekjunk@foobar.com> wrote or quoted:
>If it's matching the empty string '' then why don't we get NA,NA1 etc 
>for ,1

| How Regex Engines Handle Lookarounds and Empty Matches
| 
| In regular expressions, lookarounds - including lookaheads (?= . . . )
| and lookbehinds (?<= . . . ) - are /zero-width assertions/. They act 
| as /conditional checks/. They inspect the string to see if a pattern
| exists, but they do not "consume" (wipe out or move past) any charac-
| ters.
| 
| Understanding how a regex engine processes these assertions requires
| looking at two distinct phases: /evaluation within a single match
| attempt/, and /progression through the string/.
| 
| 1. The Fixed-Position Rule (Chaining Lookarounds)
| 
| When a regex engine tests a pattern at a specific position in a
| string, the internal pointer stays completely still until the entire
| pattern either succeeds or fails.
| 
| If you chain multiple lookarounds together, they all evaluate
| from the exact same spatial slot, one after the other.
| 
| Example: Chaining Lookaheads
| 
| Consider the pattern "(?=x)(?=x)" applied to the string "xy".
| 
| 1.  The engine starts at Position 0 (the empty space right before 
|     "x").
| 
| 2.  First "(?=x)" check: Looks ahead from Position 0, sees "x", and
|     returns "True". The pointer does not move.
| 
| 3.  Second "(?=x)" check: Looks ahead from the same Position 0, sees 
|     "x" again, and returns "True". The pointer does not move.
| 
| Both assertions pass at Position 0. The engine declares a match of 
| length zero at that position. If one's using a substitution function
| like Python's "re.sub(r'(?=x)(?=x)?, 'z', ?xy')", it inserts "z" at
| that empty slot, resulting in "zxy".
| 
| 2. The Forced-Advance Rule (Preventing Infinite Loops)
| 
| If lookarounds don't move the pointer, why doesn't a global "search 
| and replace" loop forever, inserting infinitely many "z" at Position 
| 0?
| 
| Regex engines implement a universal safety mechanism: /The Forced-
| Advance Rule/.
| 
| Standard Match   If a regex matches actual characters (like "[^,]+"),
| the pointer naturally moves past those characters for the next search
| cycle.
| 
| Zero-Width Match   If a regex matches an empty string (zero width),
| the engine applies the safety rule. After completing the match and
| performing any substitution, /it forces the pointer forward by exactly
| one position/ before attempting the next match.
| 
| Edge Cases & Common Logic Traps
| 
| Edge Case A: Contradictory Lookarounds
| 
| What happens if you look ahead for two different characters at the
| same time?
| 
| (?=x)(?=y)
| 
| Result   This will never match anything.
| 
| Why   At any given empty slot in a string, the single character
| immediately following that slot cannot be both "x" and "y" simul-
| taneously.
| 
| Edge Case B: Conflicting Lookahead and Lookbehind
| 
| You can combine lookaheads and lookbehinds to pinpoint exact
| boundaries.
| 
| (?<=x)(?=y)
| 
| Result   This successfully matches the empty space between an "x" and
| a "y" (such as inside the string "xy").
| 
| Why   At Position 1 (between "x" and "y"), the lookbehind looks back-
| ward and sees "x" ("True"), while the lookahead looks forward and sees 
| "y" ("True").
| 
| Edge Case C: Quantifiers on Zero-Width Matches
| 
| What happens if you tell a lookaround to repeat using a quantifier
| like "*" (zero or more times)?
| 
| (?=x)*
| 
| Result   This creates an immediate zero-width match at every single
| position in the string, even where "x" does not exist.
| 
| Why   At a position where "x" is absent, "(?=x)" fails. However, 
| because "*" means "zero or more times," matching it zero times is 
| considered a total success. The engine registers an empty match, 
| forces the pointer forward by one via the safety rule, and repeats
| this at every slot.

  Lines marked with "| " come from my editing, where I start by writing
  prompts for the chatbot and then edit the generated texts and format
  them for USENET.

Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

re.sub(r'((?<=\A)|(?<=,))(?=,|\Z)', 'NA', ',1,,,two,3,,,') how does it work? Veek M <veekjunk@foobar.com> - 2026-08-09 00:21 +0000
  Re: re.sub(r'((?<=\A)|(?<=,))(?=,|\Z)', 'NA', ',1,,,two,3,,,') how does it work? Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-08-09 01:26 +0000
  Re: re.sub(r'((?<=\A)|(?<=,))(?=,|\Z)', 'NA', ',1,,,two,3,,,') how does it work? ram@zedat.fu-berlin.de (Stefan Ram) - 2026-08-09 11:24 +0000
    Re: re.sub(r'((?<=\A)|(?<=,))(?=,|\Z)', 'NA', ',1,,,two,3,,,') how does it work? Veek M <veekjunk@foobar.com> - 2026-08-11 09:21 +0000

csiph-web