PiWo
PiWo

Reputation: 620

How to escape unicode special chars in string and write it to UTF encoded file

What I aim to achieve is to:

string like:

Bitte überprüfen Sie, ob die Dokumente erfolgreich in System eingereicht wurden, und löschen Sie dann die tatsächlichen Dokumente.

convert to:

'Bitte \u00FCberpr\u00FCfen Sie, ob die Dokumente erfolgreich in System eingereicht wurden, und l\u00F6schen Sie dann die tats\u00E4chlichen Dokumente.'

and write it in this form to file (which is UTF-8 encoded).

Upvotes: 3

Views: 1723

Answers (2)

S.B
S.B

Reputation: 16506

A simple solution would be ascii():

string = 'Bitte überprüfen Sie, ob die Dokumente erfolgreich in System ' \
         'eingereicht wurden, und löschen Sie dann die tatsächlichen Dokumente.'

print(ascii(string))

output :

'Bitte \xfcberpr\xfcfen Sie, ob die Dokumente erfolgreich in System eingereicht wurden, und l\xf6schen Sie dann die tats\xe4chlichen Dokumente.'

Also you can use unicode-escape and raw-unicode-escape to achive this (link) :

string = 'Bitte überprüfen Sie, ob die Dokumente erfolgreich in System ' \
         'eingereicht wurden, und löschen Sie dann die tatsächlichen Dokumente.'

print(string.encode('unicode-escape').decode('raw-unicode-escape'))

output :

Bitte \xfcberpr\xfcfen Sie, ob die Dokumente erfolgreich in System eingereicht wurden, und l\xf6schen Sie dann die tats\xe4chlichen Dokumente.

Note : ascii() will escape non-ascii characters with \x , \u, \U for 1 byte, 2 bytes and 4 bytes respectively. In your case you see \x. But try this one :

print(ascii('س'))  # '\u0633'

If you really want to convert \xhh escape sequences to \u00hh , use re.sub() on result of ascii():

import re
print(re.sub(r'\\x[a-f0-9]{2}', lambda x: r'\u00' + x.group()[-2:].upper(), ascii(string))) 

output :

'Bitte \u00FCberpr\u00FCfen Sie, ob die Dokumente erfolgreich in System eingereicht wurden, und l\u00F6schen Sie dann die tats\u00E4chlichen Dokumente.'

Above approaches works for escaping any non-ascii characters, if you intend to escape just those three Germany's alphabets and there is no other non-ascii characters, take a look at str.translate() method.

Upvotes: 3

Jiří Baum
Jiří Baum

Reputation: 6930

Another solution, not relying on the built-in repr() but rather implementing it from scratch:

orig = 'Bitte überprüfen Sie, ob die Dokumente erfolgreich in System eingereicht wurden, und löschen Sie dann die tatsächlichen Dokumente.'

enc = re.sub('[^ -~]', lambda m: '\\u%04X' % ord(m[0]), orig)

print(enc)

Differences:

  • Encodes only using \u, never any other sequence, whereas repr() uses about a third of the alphabet (so for example the BEL character will be encoded as \u0007 rather than \a)
  • Upper-case encoding, as specified (\u00FC rather than \u00fc)
  • Does not handle unicode characters outside plane 0 (could be extended easily, given a spec for how those should be represented)
  • It does not take care of any pre-existing \u sequences, whereas repr() turns those into \\u; could be extended, perhaps to encode \ as \u005C:
    enc = re.sub(r'[^ -[\]-~]', lambda m: '\\u%04X' % ord(m[0]), orig)
    

Upvotes: 5

Related Questions