0

Is there an indicated way in Python 3 to copy compiled regular expressions? The following code throws a TypeError (same with deepcopy), and I am not sure where to go from there.

import re
import copy

p = re.compile( r'foo' )
copy.copy(p) # TypeError: cannot copy this pattern object

I have thought of creating a copy manually with:

p_copy = re.compile(p.pattern, p.flags)

but I wonder if this is correct for all possible regexes; if it were that simple, then why would the reference library not implement copy like this?

Jonathan H
  • 7,591
  • 5
  • 47
  • 80
  • 5
    What would be the point? They're immutable. – user2357112 Apr 13 '20 at 20:07
  • Then it is even simpler; it would just need to return itself, wouldn't it? The fact that it is not implemented is troublesome when working with classes that contain compiled regexes as members, because it requires writing a custom `__copy__` method. Am I missing something obvious? – Jonathan H Apr 13 '20 at 20:11
  • 1
    If that's the issue, then you're right that it's troublesome, which is why it got fixed in 3.7 - trying to copy a pattern through the `copy` module will now return the pattern object passed in. – user2357112 Apr 13 '20 at 20:13
  • You almost certainly do not need to compile it yourself anyway. Every regular expression gets cached the first time you use it. Unless you use more than 512 regular expressions, the cached object never expires. – chepner Apr 13 '20 at 20:13
  • (The cache isn't an LRU cache; when you try to use the 513th unique regular expression, the entire cache is cleared. However, it's unlikely the cost of having to recompile a regular expression occasionally will be any kind of bottleneck in your program.) – chepner Apr 13 '20 at 20:15
  • @chepner Many thanks for the tip. I am writing a parsing library, so in my case, it is not unlikely that more than 512 regexes will be used. – Jonathan H Apr 13 '20 at 20:18
  • Was fixed in *Python 3. **7***. – CristiFati Apr 13 '20 at 20:23
  • Well, as ask in 2018 deepcopy doesn't have method to copy Patterns, you might extend copy method with regex patterns class. This might help https://stackoverflow.com/q/6279305/12422518 – furkanayd Apr 13 '20 at 20:25

1 Answers1

2

Since compiled regexes are immutable, a new reference is effectively the same as a copy.

p = re.compile( r'foo' )
p_copy = p

(If after writing the above the contents of p_copy aren't suitable for your purposes, provide more context in your question!)

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • That's a perfectly fine answer, thank you. My issue was that I didn't understand why copy was not implemented by default for compiled regexes, as this causes issues when trying to copy classes that contain them as members, but apparently this was fixed in Python 3.7 (see comments on my question). – Jonathan H Apr 13 '20 at 20:17