O'Skywalker
O'Skywalker

Reputation: 701

Python only replace string which is not C++ comment

I want to deal only with string which is NOT C++ comment, here is the pattern to find out C++ comment:

pattern = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE)

However, I don't know how to make it to work as my intention.

# Python 3.4.2
s = '''
/****
C++ comments
  //pResMgr->CreateDialogEx();
****/
//pResMgr->CreateDialogEx();
/*//pResMgr->CreateDialogEx();*/

// real code, I want to replace only this following line of code
pResMgr->CreateDialogEx();
'''

newS = s.replace('CreateDialogEx', 'Create')
print(newS)

My expected output is:

/****
C++ comments
  //pResMgr->CreateDialogEx();
****/
//pResMgr->CreateDialogEx();
/*//pResMgr->CreateDialogEx();*/

// real code, I want to replace only this following line of code
pResMgr->Create();

Upvotes: 2

Views: 280

Answers (1)

Martin Gottweis
Martin Gottweis

Reputation: 2739

Didn't test it, but it works it with your case and fundamentally should work. It basically goes throught the text finding newline, // or /* and then handling the cases. Really simple, no regex.

source_code = '''//pResMgr//->CreateDialogEx();'''

def indexOf(string, character):
    return string.index(character) if character in string else 9999999

def replaceNotInComments(string, searchFor, replaceWith):
    result = ''
    nextBreak = 0
    while True:
        nextBreak = min(indexOf(string, '\n'),
                        indexOf(string, '/*'),
                        indexOf(string, '//'))
        if nextBreak == 9999999:
            result += string.replace(searchFor, replaceWith);
            break
        result += string[0:nextBreak].replace(searchFor, replaceWith);

        if nextBreak == indexOf(string, '\n'):
            string = string[nextBreak+1:]

        if nextBreak == indexOf(string, '/*'):
            string = string[nextBreak+2:]
            result += '/*'+string[0:indexOf(string, '*/')+2]
            string = string[indexOf(string, '*/')+2:]

        if nextBreak == indexOf(string, '//'):
            string = string[nextBreak+2:]
            if result != '':
                result += '\n'  
            result += string[0:indexOf(string, '\n')+1]
            string = string[indexOf(string, '\n')+1:]


    return result

result = replaceNotInComments(source_code, 'CreateDialogEx', 'Create')
print(result)

Upvotes: 2

Related Questions