user3410960
user3410960

Reputation: 473

replace not working in Python 3 for bytes

Python version: 3.5.2
my codes:

a = b"\xff"
b = a.replace(b"f", b"d")
print(b)

I got b'\xff'. I tried another way. Fisrt, i converted bytes to str, then replaced the string.

a = b"\xff"
b = a.decode()
b = b.replace("f", "d")

but through exception:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

I don't know how to fix the problem in python3. What should I do?

Upvotes: 4

Views: 15397

Answers (2)

wdt12
wdt12

Reputation: 514

I assume your trying to replace the f’s in \xff with d’s to get \xdd. You cannot use the function string.replace() for that for the same reason you can’t call "\t".replace("t", "n") and get \n, which BrenBarn has already pointed out. One thing that you could do is use \\xff instead of \xff, although I don’t know if that’s an option for you. Here’s what that would look like in your code:

a = b"\\xff"
b = a.replace(b"f", b"d")
print(b)

Which would output \\xdd. If that’s not an option, I would suggest making your own function for that. I’ll show you how to do that just to get you on the right track, but just to keep things simple, I’m going to assume that your only dealing with one character inputs. The reason that you can’t simply replace the f’s with d’s is because there is no actual f in the first place, so your function would have to start by converting the character to \\xff. Then you would go on to replace the f’s with d’s. Here’s what that looks like in code:

def convertHexToString(char):
    return "\\x" + str(hex(ord(char)))[2:]

a = convertHexToString("\xff")
b = a.replace("f", "d")
print(b)

Which would output \xdd. Notice that the output is \\xdd and not actually \xdd, although that’s what it looks like. In order to turn it into that, you would have to do something like this:

def convertStringToHex(string):
    return bytes(string, “utf-8").decode("unicode_escape")

So, your final program would look like this:

def convertHexToString(char):
    return "\\x" + str(hex(ord(char)))[2:]

def convertStringToHex(string):
    return bytes(string, "utf-8").decode("unicode_escape")

# Here we are changing the f's to d's
a = convertHexToString("\xff")  # \\xff
b = a.replace("f", "d")         # \\xdd
print(b)

# Here we are converting the string '\\xdd' into '\xdd'
b = convertStringToHex(b)

Upvotes: 6

BrenBarn
BrenBarn

Reputation: 251428

There is no b"f" in b'\xff'. You type an "f" to enter b'\xff', but that's just one of several input methods; the value is the same as, for instance, bytes([255]). .replace only replaces bytes that are actually in the string; it doesn't know how you created the string.

Once the string is created, the details of the input method you used to create it are gone. You can't do what you're trying to do for the same reason you can't do '\t'.replace('t', 'n') to get '\n'. '\t' doesn't contain a "t"; you just type a "t" as a means of specifying a tab character.

Upvotes: 6

Related Questions