Python:从非 BMP unicode 字符中查找等效代理对
Python: Find equivalent surrogate pair from non-BMP unicode char
此处提供的答案: 告诉您如何将代理项对(例如 '\ud83d\ude4f'
)转换为单个非 BMP unicode 字符(答案为 "\ud83d\ude4f".encode('utf-16', 'surrogatepass').decode('utf-16')
)。我想知道如何反向执行此操作。我如何使用 Python 从非 BMP 字符中找到等效的代理项对,将 '\U0001f64f'
() 转换回 '\ud83d\ude4f'
。我找不到明确的答案。
您必须用代理对手动替换每个非 BMP 点。您可以使用正则表达式执行此操作:
import re
_nonbmp = re.compile(r'[\U00010000-\U0010FFFF]')
def _surrogatepair(match):
char = match.group()
assert ord(char) > 0xffff
encoded = char.encode('utf-16-le')
return (
chr(int.from_bytes(encoded[:2], 'little')) +
chr(int.from_bytes(encoded[2:], 'little')))
def with_surrogates(text):
return _nonbmp.sub(_surrogatepair, text)
演示:
>>> with_surrogates('\U0001f64f')
'\ud83d\ude4f'
有点复杂,但这里是转换单个字符的一行代码:
>>> emoji = '\U0001f64f'
>>> ''.join(chr(x) for x in struct.unpack('>2H', emoji.encode('utf-16be')))
'\ud83d\ude4f'
要转换混合字符,需要用另一个表达式包围该表达式:
>>> emoji_str = 'Here is a non-BMP character: \U0001f64f'
>>> ''.join(c if c <= '\uffff' else ''.join(chr(x) for x in struct.unpack('>2H', c.encode('utf-16be'))) for c in emoji_str)
'Here is a non-BMP character: \ud83d\ude4f'
此处提供的答案:'\ud83d\ude4f'
)转换为单个非 BMP unicode 字符(答案为 "\ud83d\ude4f".encode('utf-16', 'surrogatepass').decode('utf-16')
)。我想知道如何反向执行此操作。我如何使用 Python 从非 BMP 字符中找到等效的代理项对,将 '\U0001f64f'
() 转换回 '\ud83d\ude4f'
。我找不到明确的答案。
您必须用代理对手动替换每个非 BMP 点。您可以使用正则表达式执行此操作:
import re
_nonbmp = re.compile(r'[\U00010000-\U0010FFFF]')
def _surrogatepair(match):
char = match.group()
assert ord(char) > 0xffff
encoded = char.encode('utf-16-le')
return (
chr(int.from_bytes(encoded[:2], 'little')) +
chr(int.from_bytes(encoded[2:], 'little')))
def with_surrogates(text):
return _nonbmp.sub(_surrogatepair, text)
演示:
>>> with_surrogates('\U0001f64f')
'\ud83d\ude4f'
有点复杂,但这里是转换单个字符的一行代码:
>>> emoji = '\U0001f64f'
>>> ''.join(chr(x) for x in struct.unpack('>2H', emoji.encode('utf-16be')))
'\ud83d\ude4f'
要转换混合字符,需要用另一个表达式包围该表达式:
>>> emoji_str = 'Here is a non-BMP character: \U0001f64f'
>>> ''.join(c if c <= '\uffff' else ''.join(chr(x) for x in struct.unpack('>2H', c.encode('utf-16be'))) for c in emoji_str)
'Here is a non-BMP character: \ud83d\ude4f'