0

I'm trying to match this:

text = "111111"
reps = 2

f_pattern = re.compile(rf"(\w)(?=\1{{reps}})")
f_matches = re.findall(f_pattern, text)
## returns: []

r_pattern = re.compile(r"(\w)(?=\1{2})")
r_matches = re.findall(r_pattern, text)
## returns: ['1', '1', '1', '1']

How should the f-string pattern be written to return non-empty result?

AbreQueVoy
  • 1,748
  • 8
  • 31
  • 52
  • 1
    This is just a typo and a very-well known issue (already collected 1727 upvotes!): `{reps}` is a variable expanded in the f-string, and you need `{{` to define a literal `{` and `}}` to define a literal `}`. – Wiktor Stribiżew Feb 16 '21 at 15:21

3 Answers3

3

Write rf"(\w)(?=\1{{{reps}}})") instead of rf"(\w)(?=\1{{reps}})").

{{ is a way to escape single { inside any f-string, same for }.

Try it online!

Arty
  • 14,883
  • 6
  • 36
  • 69
0

As mentioned in this answer:

How do I use format() in re.compile

Double braces are interpreted as literal braces in format strings. You need another, third set, to indicate that len is a formatted expression.

If you use double brace, f-string thinks its a literal brace and skips it. use 3 braces so 2 of the braces will be considered as a literal brace and another set for format string.

MoPo
  • 85
  • 1
  • 3
0

You need to double the curly bracket for literal print. so here is the solution

text = "111111"
reps = 2
 
f_pattern = re.compile(rf"(\w)(?=\1{{ {reps} }})")
f_matches = re.findall(f_pattern, text)
MubtadaNaqvi
  • 187
  • 12