python - 使用带字节数的 textwrap.wrap

标签 python python-3.x split word-wrap python-unicode

如何使用 textwrap 模块在一行达到一定字节数之前进行拆分(不拆分多字节字符)?

我想要这样的东西:

>>> textwrap.wrap('☺ ☺☺ ☺☺ ☺ ☺ ☺☺ ☺☺', bytewidth=10)
☺ ☺☺
☺☺ ☺
☺ ☺☺
☺☺

最佳答案

结果取决于使用的编码,因为每个字节数 字符是编码的函数,在许多编码中, 性格也是如此。我假设我们使用的是 UTF-8,其中 '☺' 是 编码为 e298ba 并且是三个字节长;给定的例子是 与该假设一致。

textwrap 中的所有内容都适用于字符;它什么都不知道 关于编码。解决此问题的一种方法是将输入字符串转换为 另一种格式,每个字符变成一串字符 其长度与字节长度成正比。我会用三个 字符:两个十六进制字节,加上一个控制换行符。 因此:

'a' -> '61x'         non-breaking
' ' -> '20 '         breaking
'☺' -> 'e2x98xbax'   non-breaking

为简单起见,我假设我们只在空格处打断,而不是制表符或任何 其他角色。

import textwrap

def wrapbytes(s, bytewidth, encoding='utf-8', show_work=False):
    byts = s.encode(encoding)
    encoded = ''.join('{:02x}{}'.format(b, ' ' if b in b' ' else 'x')
                      for b in byts)
    if show_work:
        print('encoded = {}\n'.format(encoded))
    ewidth = bytewidth * 3 + 2
    elist = textwrap.wrap(encoded, width=ewidth)
    if show_work:
        print('elist = {}\n'.format(elist))
    # Remove trailing encoded spaces.
    elist = [s[:-2] if s[-2:] == '20' else s for s in elist]
    if show_work:
        print('elist = {}\n'.format(elist))
    # Decode. Method 1: inefficient and lengthy, but readable.
    bl1 = []
    for s in elist:
        bstr = "b'"
        for i in range(0, len(s), 3):
            hexchars = s[i:i+2]
            b = r'\x' + hexchars
            bstr += b
        bstr += "'"
        bl1.append(eval(bstr))
    # Method 2: equivalent, efficient, terse, hard to read.
    bl2 = [eval("b'{}'".format(''.join(r'\x{}'.format(s[i:i+2])
                                       for i in range(0, len(s), 3))))
             for s in elist]
    assert(bl1 == bl2)
    if show_work:
        print('bl1 = {}\n'.format(bl1))
    dlist = [b.decode(encoding) for b in bl1]
    if show_work:
        print('dlist = {}\n'.format(dlist))
    return(dlist)

result = wrapbytes('☺ ☺☺ ☺☺ ☺ ☺ ☺☺ ☺☺', bytewidth=10, show_work=True)
print('\n'.join(result))

关于python - 使用带字节数的 textwrap.wrap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36244817/

相关文章:

python - 正则表达式命名组

python - SQLAlchemy 是否与 Django 的 get_or_create 等效?

python - 如何通过pip安装websocket 8.1

Python 和 Julia 以不同的方式计算函数?

JavaScript 变量分成组

python - 查看与可查看并显示小部件

python - Python 的内置 __build_class__ 有什么作用?

java - 分割此文本文件的最佳方法是什么?

sql-server - SQL - 将 Varchar 值转换为数据类型 Int 时转换失败

python - 严格类型会提高 Python 程序性能吗?