I am reading the Python Cookbook 3rd Edition and came across the topic discussed in 2.6 "Searching and Replacing Case-Insensitive Text," where the authors discuss a nested function that is like below:
def matchcase(word):
def replace(m):
text = m.group()
if text.isupper():
return word.upper()
elif text.islower():
return word.lower()
elif text[0].isupper():
return word.capitalize()
else:
return word
return replace
If I have some text like below:
text = 'UPPER PYTHON, lower python, Mixed Python'
and I print the value of 'text' before and after, the substitution happens correctly:
x = matchcase('snake')
print("Original Text:",text)
print("After regsub:", re.sub('python', matchcase('snake'), text, flags=re.IGNORECASE))
The last "print" command shows that the substitution correctly happens but I am not sure how this nested function "gets" the:
PYTHON, python, Python
as the word that needs to be substituted with:
SNAKE, snake, Snake
How does the inner function replace get its value 'm
'?
When matchcase('snake
') is called, word takes the value 'snake
'.
Not clear on what the value of 'm
' is.
Can any one help me understand this clearly, in this case?
Thanks.
When you pass a function as the second argument to
re.sub
, according to the documentation:The
matchcase()
function itself returns thereplace()
function, so when you do this:what happens is that
matchcase('snake')
returnsreplace
, and then every non-overlapping occurrence of the pattern'python'
as a match object is passed to thereplace
function as them
argument. If this is confusing to you, don't worry; it is just generally confusing.Here is an interactive session with a much simpler nested function that should make things clearer:
So
f = foo('hello')
is assigning a function that looks like the one below to a variablef
:f
can then be called like thisf('world')
, which is like callingbar('world')
. I hope that makes things clearer.