8

I have a string which looks like below

string = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"

Now I want to replace every occurrence of SELECT except the first one with @@@SELECT so that in the end string looks like this

"SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff"

Now Python replace() replaces all occurrence of SELECT.

string = string.replace("SELECT", "@@@SELECT)

So the string becomes

"@@@SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff"

How do I ensure except the first instance, everything else is replaced?

Note: The string can have n occurrences of SELECT

7 Answers 7

10

With additional "reversed" substitution step:

s = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"
res = s.replace("SELECT", "@@@SELECT").replace("@@@SELECT", "SELECT", 1)
print(res)

The output:

SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff

A more sophisticated, but ensuring target word boundaries, could be as below:

import re

def make_replacer():
    rpl = ''
    def inner(m):
        nonlocal rpl
        res = rpl + m.group()
        rpl = '@@@'
        return res
    return inner

s = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"
res = re.sub(r'\bSELECT\b', make_replacer(), s)
print(res)   # SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff
Sign up to request clarification or add additional context in comments.

Comments

4

You can use itertools.count with re.sub:

import re, itertools
c = itertools.count()
string = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"
r = re.sub(r"\bSELECT\b", lambda x:x.group() if not next(c) else f'@@@{x.group()}', string)

Output:

'SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff'

However, if SELECT is always placed at the start of the string, you can use a negative lookbehind:

r = re.sub('(?<!^)SELECT', lambda x:f'@@@{x.group()}', string)

Output:

'SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff'

Comments

3

You can use the method partition and replace. The working code looks like:

string = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"
parts = string.partition("SELECT")  # returns a tuple
results = parts[0] + parts[1] + parts[2].replace("SELECT", "@@@SELECT")

print(results)

So you will get:

SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff

If string = "Blabla is SELECT sdfdsf SELECT sdrrr SELECT 5445ff", you will get:

Blabla is SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff

Comments

3

How about just skipping the first 3 letters of what you have?

string = string.replace("SELECT", "@@@SELECT)[3:]

Comments

1
import string

def removeExceptFirst(s, old, new):
    i = s.find(old) + len(old)
    newStr = s[0:i]
    newStr += s[i:].replace(old, new)
    return newStr

print(removeExceptFirst("SELECT sdfdsf SELECT sdrrr SELECT 5445ff", "SELECT", "@@@SELECT"))

The Output:

SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff

Comments

1

One more approach:

import re
from itertools import chain, repeat
string = 'SELECT sdfdsf SELECT sdrrr SELECT 5445ff'
string = ''.join(x + s for x, s in zip(chain(['', 'S'], repeat('@@@S')), re.split(r'\bS(?=ELECT\b)', string)))
print(string)

Output:

SELECT sdfdsf @@@SELECT sdrrr @@@SELECT 5445ff

Comments

0

use this code (more simple and only use split and replace)

string = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"
string = "SELECT " + string.split('SELECT', 1)[1].strip().replace('SELECT', '@@@SELECT').strip()

But if there's a text before the SELECT, use

string = "SELECT sdfdsf SELECT sdrrr SELECT 5445ff"
string = string.split('SELECT', 1)[0].strip() + " SELECT " + string.split('SELECT', 1)[1].strip().replace('SELECT', '@@@SELECT').strip()

That code remove the first SELECT and then replace all the SELECT sub-string and then add the SELECT string to the main string

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.