TaoTao
TaoTao

Reputation: 515

Conditional regex replacement

With Python, You can check if a group is empty before replacing text?

Example:

[user] John Marshal   -->   [user]<br><strong>Jonh Marshal<strong>

John Marshal   -->   <strong>Jonh Marshal<strong>

The regex should use this is, but with the "condition" to insert the < br> only if group 1 is found.

title = re.sub(r'^\s*(\[.*?\])?\s*(.*)', r'\1<br><strong>\2</strong>', title)

Upvotes: 4

Views: 8028

Answers (2)

Denis Nutiu
Denis Nutiu

Reputation: 1433

To do conditional substitutions with regex in Python I've came up with the following solution:

@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: 0

Martijn Pieters
Martijn Pieters

Reputation: 1122222

Group one is always found because you allow empty matches.

You want to match at least one character, not 0 or more, so use .+?:

title = re.sub(r'^\s*(\[.+?\])?\s*(.*)', r'\1<br><strong>\2</strong>', title)

Now the match will throw an exception if group one is missing. Make use of that:

try:
    title = re.sub(r'^\s*(\[.+?\])?\s*(.*)', r'\1<br><strong>\2</strong>', title)
except re.error:
    title = re.sub(r'^\s*(.*)', r'<strong>\1</strong>', title)

The alternative is to use a function to do the replacement:

def title_sub(match):
    if match.group(1):
        return '{}<br><strong>{}</strong>'.format(*match.groups())
    return '<strong>{}</strong>'.format(match.group(2))

title = re.sub(r'^\s*(\[.+?\])?\s*(.*)', title_sub, title)

Demo:

>>> re.sub(r'^\s*(\[.+?\])?\s*(.*)', title_sub, '[user] John Marshal')
'[user]<br><strong>John Marshal</strong>'
>>> re.sub(r'^\s*(\[.+?\])?\s*(.*)', title_sub, 'John Marshal')
'<strong>John Marshal</strong>'

Upvotes: 10

Related Questions