Apollo
Apollo

Reputation: 9064

Passing two arguments to replace function for Re.sub

How can I pass two variables to my replace function?

I have defined it as

def replace(line,suppress)

Calling it like so:

line = re.sub(r'''(?x)
                    ([\\]*\$\*)|
                    ([\\]*\$\{[0-9]+\})|
                    ([\\]*\$[0-9]+)|
                    ([\\]*\$\{[a-zA-Z0-9_]+\-.*\})|
                    ([\\]*\$\{[a-zA-Z0-9_]+\=.*\})|
                    ([\\]*\$[a-zA-Z0-9_]+)|
                    ([\\]*\$\{[a-zA-Z0-9_]+\})|
                    ([\\]*\$[\{]+.*)
                    ''',replace,line,suppress)

Receiving error:

return _compile(pattern, flags).sub(repl, string, count)
TypeError: replace() takes exactly 2 arguments (1 given)

Upvotes: 6

Views: 4276

Answers (2)

three_pineapples
three_pineapples

Reputation: 11869

As has been mentioned, when re.sub calls your function, it only passes one argument to it. The docs indicate this is a match object (presumably the line variable?)

If you want to pass additional arguments, you should wrap your function up in a lambda expression.

So something like:

re.sub('...', lambda line: replace(line, suppress))

or

re.sub('...', lambda line, suppress=suppress: replace(line, suppress))

Note the use of suppress=suppress in the signature of the second lambda. This is there to ensure the value of suppress used is the value of suppress when the lambda was defined. Without that, the value of suppress used is the value of suppress when the function is executed. In this case, it actually wouldn't matter (as the lambda is used immediately after definition, so suppress will never be changed between definition and execution), but I think it's important you understand how lambda works for using it in the future.

Upvotes: 10

David Sanders
David Sanders

Reputation: 4139

Re.sub only accepts function for its repl argument which take one value. That's defined in the implementation of Re.sub. You don't have access to it.

Upvotes: 0

Related Questions