user2064000
user2064000

Reputation:

Is there a way to replace regexes dynamically in Python?

Some programming languages offer the ability to perform a regex replacement dynamically.

For instance, say we have a string like foo:$USER:$GROUP, where $USER and $GROUP will be replaced by their environment variables. The transformed string would look something like foo:john:admin. To solve this problem, we have to take all the strings matching \$[A-Za-z]+ and look up the environment variable value.

In PHP, the following looks like this:

<?php
preg_replace_callback(
   # the regular expression to match the shell variables.
   '/\$[A-Za-z]+/',
   # Function that takes in the matched string and returns the environment
   # variable value.
   function($m) {
     return getenv(substr($m[0], 1));
  },
  # The input string.
  'foo:$USER:$GROUP'
);

Is there a similar thing in Python?

Upvotes: 4

Views: 3096

Answers (3)

Mayur Vora
Mayur Vora

Reputation: 962

Yes, python provides many inbuilt function for Regular expression.

Re.sub(pattern, repl, string, count=0, flags=0)

Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. If the pattern isn’t found, string is returned unchanged. repl can be a string or a function; if it is a string, any backslash escapes in it are processed. That is, \n is converted to a single newline character, \r is converted to a carriage return, and so forth. Unknown escapes such as \j are left alone. Backreferences, such as \6, are replaced with the substring matched by group 6 in the pattern.

Syntex

import re
result = re.sub(pattern, callback, subject)
result = re.sub(pattern, callback, subject, limit)

Useful Link,
https://docs.python.org/2/library/re.html

Solution

import re, os

def replaceFunction(matchobj):
     if matchobj.group(0) == "$USER":
    return os.getenv(matchobj.group(1))
     elif matchobj.group(0) == "$GROUP":
    return os.getenv(matchobj.group(1))

print re.sub(r'\$([A-Za-z]+)', replaceFunction, 'foo:$USER:$GROUP')

Upvotes: 2

Denis Nutiu
Denis Nutiu

Reputation: 1433

You could use something like this:

@classmethod
def normalize_query_string(cls, query_string):

    def replace_fields(match):
        x = match.group("field")
        if x == "$certHash":
            return "ci.C.H:"
        return "{}:".format(x)

    result = re.sub(r"(?P<field>\$[\w.]+):", replace_fields, query_string)
    return result

Upvotes: 2

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626893

You may use re.sub with a lambda expression or a similar to PHP callback method.

import re, os

s = 'foo:$USER:$GROUP'
rx = r'\$([A-Za-z]+)'
result = re.sub(rx, lambda m: os.getenv(m.group(1)), s)
print(result)

The \$([A-Za-z]+) pattern matches $ and then captures 1 or more ASCII letters into Group 1. Inside the lambda expression, the m represent the match data object. The USER or GROUP is inside m.group(1).

Upvotes: 11

Related Questions