1

I would like to replace every symbol of a word after - with *.

For example:

asd-wqe ffvrf    =>    asd-*** ffvrf

In TS regex it could be done with (?<=-\w*)\w and replacement *. But default python regex engine requires lookbehinds of fixed width.

Best I can imaging is to use

(?:(?<=-)|(?<=-\w)|(?<=-\w{2}))\w

and repeat lookbehing some predetermined big number of times, but it seems not very sustainable or elegant.

Is it possible to use default re module for such a task with some more elegant pattern?

Demo for testing here.

P.S. I'm aware that alternative regex engines, that support lookbehind of variable length exist, but would like to stick with default one for a moment if possible.

markalex
  • 8,623
  • 2
  • 7
  • 32

2 Answers2

2

I think you can not do that with Python re, as you want to match a single character knowing that to the left is - followed by optional word characters.

I would write it like this with a callback and then get the length of the match for the replacement of the * chars

import re

strings = [
    "asd-wqe ffvrf",
    "asd-ss sd",
    "a-word",
    "a-verylongword",
    "an-extremelyverylongword"
]
pattern = r"(?<=-)\w+"
for s in strings:
    print(re.sub(pattern, lambda x: len(x.group()) * "*", s))

Output

asd-*** ffvrf
asd-** sd
a-****
a-************
an-*********************

See a python demo.


An alternative to a quantifier in a lookbehind assertion is using the \G anchor (which is also not supported by Python re)

 (?:-|\G(?!^))\K\w

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

You can capture all the word characters after - and pass a callback to re.sub that replaces the match with a string of asterisks of the same length.

s = 'asd-wqe ffvrf'
res = re.sub(r'(?<=-)\w+', lambda m: '*' * len(m.group()), s)
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • 1
    [Try it online!](https://tio.run/##Fcw9EoIwEAbQPqf4ut1FoLFzZLyITRgSZYb8uAkynj5q@4qXP/WZ4rm1NeSkFepMwQSyZRmOl4P3b/Vk1P1V3Vj2mZX4dp0GuR8n6rHZMC8W4QLqCB02FzmMD017ZpEeRUzWNVb@HdLaFw) – Unmitigated Apr 10 '23 at 15:52
  • Thank you. I'm new to python, and wasn't aware of possibility to pass callback to `re.sub()` – markalex Apr 10 '23 at 16:02