Reputation: 61
I am trying to switch two elements in the string while keeping all the other characters untouched. Here is an example:
Original string:
r'xyzA*12*pqR*stB*HS*lmN*opA*45*a4N*gB*SD*drtU*ghy'
Required output:
r'xyzA*HS*pqR*stB*12*lmN*opA*SD*a4N*gB*45*drtU*ghy'
Notice that element after A* and B* are switched.
I was able to compile a RegEx pattern that gives me elements to replace like following:
>>> import re
>>> pattern = re.compile(r'A\*(.*?)\*.*?B\*(.*?)\*')
>>> M = pattern.findall(string)
>>> M
[('12', 'HS'), ('45', 'SD')]
After this stage I need your help to find out how to use sub to get the required string.
Upvotes: 5
Views: 601
Reputation: 21
Alternatively, you could also solve this with string find and a loop instead of regular expressions:
str = r'xyzA*12*pqR*stB*HS*lmN*opA*45*a4N*gB*SD*drtU*ghy'
result = ""
start = 0
while (str.find("A*", start) > -1):
aStart = str.find("A*", start)+2
aEnd = str.find("*", aStart)
bStart = str.find("B*", aEnd)+2
bEnd = str.find("*", bStart)
result += str[start:aStart]+str[bStart:bEnd]+str[aEnd:bStart]+str[aStart:aEnd]
start = bEnd
result += str[start:]
print result
#xyzA*HS*pqR*stB*12*lmN*opA*SD*a4N*gB*45*drtU*ghy
Upvotes: 1
Reputation: 214927
One option is to capture the pattern between the two interested patterns as well and use back reference to reorder them:
s = r'xyzA*12*pqR*stB*HS*lmN*opA*45*a4N*gB*SD*drtU*ghy'
import re
pattern = re.compile(r'A\*(.*?)(\*.*?B\*)(.*?)\*')
#keep the position of the second group and switch the position of the first and third group
pattern.sub(r"A*\3\2\1*", s)
# 'xyzA*HS*pqR*stB*12*lmN*opA*SD*a4N*gB*45*drtU*ghy'
Upvotes: 8