Ad
  • Custom User Avatar
  • Custom User Avatar

    Best regex resource that I know: https://regex101.com/

    Give it a regex, it gives you a point-by-point breakdown of what it does.

  • Custom User Avatar

    I gave up trying to solve it with regex, and I'm only loosely grasping this one, but I can break parts of it down.

    \B states that the match starts at something that isn't a 'word boundary', I think this ignores the commas after they're inserted. (and possibly the start of the string itself, since that will never need a comma)

    (?= [...]) is a lookahead assertion, so we're trying to test if where we're currently sitting in the string is followed by these rules. We have to use this lookahead instead of matching the digits themselves, because we're not trying to replace the actual digits, just find the right position in the string to do inserts.

    \d{3} is looking for 3 digits, and wrapping it with ( )+ wants to match that pattern one or more times.

    ?! is a negative lookahead assertion, so with (?!\d) we don't want one single occurance of a digit after our groups of 3. I think what this effectively does is snap the selection to the right hand side... working backwards in groups of 3. Seeing if we're in a valid part of the string by testing whether we can count to the end in steps of 3. (I would have gravitated towards using $ here to achor the end, but I couldn't solve it using regex, so just ignore me)

    And the /g is the global flag which I think repeats the whole operation multiple times while the condition is present.

    If you take off the /g flag and watch it run once:
    1234567 becomes:
    1,234567
    And you can see the "counting in clusters of 3 digits from the right hand side" idea working.
    And if you imagine it running again on:
    1,234567
    The position that begins 234567 doesn't qualify, because it sits with a word-boundary , to the left, so that digit gets skipped until the next valid position, which starts at 567 (becuase of the 3 digit rule). At which point the replacement repeats (because /g) and then there are no more valid matches in the string.