march_seven march_seven - 1 month ago 12
Python Question

How could I change the hex number for decimal number in re.sub

I have a string

"call 0x558f to add 0xaaef"
,and I want to change the hex numbers in that string to decimal numbers, then print out the result with those numbers re-inserted, like
"call xxxx to add xxxx"
.

I tried to code this like this:

# coding=utf-8
import re
__author__ = 'sudo'

def hextodecimal(match):
print "Return the decimal number for hex string"
print match.group()
vaule = int(hex(match.group()),16)
return vaule

p = re.compile(r"\b0[xX][0-9a-fA-F]+\b ")

print p.sub(hextodecimal, "call 0x568a to add 0x333f")


although I managed to extract the
"0x568a"
portion, there is an error:

Return the decimal number for hex string
0x568a
Traceback (most recent call last):
File "F:/pythonProject/Guessnumber/hextooct.py", line 15, in <module>
print p.sub(hextodecimal, "call 0x568a to add 0x333f")
File "F:/pythonProject/Guessnumber/hextooct.py", line 11, in hextodecimal
vaule = int(hex(match.group()),16)
TypeError: hex() argument can't be converted to hex


How can I fix it?

Answer

You need to remove the hex() call; that function used to produce hex output, not to parse it.

Group the hexadecimal digits portion of the matched text, then pass only that portion to int(..., 16), then convert that parsed integer to a string:

def hextodecimal(match):
    return str(int(match.group(1), 16)) 

p = re.compile(r"\b0[xX]([0-9a-fA-F]+)\b")
print p.sub(hextodecimal, "call 0x568a to add 0x333f")

I removed the trailing space from your pattern too.

Demo:

>>> import re
>>> def hextodecimal(match):
...     return str(int(match.group(1), 16))
...
>>> p = re.compile(r"\b0[xX]([0-9a-fA-F]+)\b")
>>> p.sub(hextodecimal, "call 0x568a to add 0x333f")
'call 22154 to add 13119'
Comments