Python字符串splitlines()删除某些Unicode控制字符

Nik*_*as9 6 python unicode

我注意到Python的标准字符串方法splitlines()实际上也删除了一些关键的Unicode控制字符.例

>>> s1 = u'asdf \n fdsa \x1d asdf'
>>> s1.splitlines()
[u'asdf ', u' fdsa ', u' asdf']
Run Code Online (Sandbox Code Playgroud)

注意"\ x1d"字符是如何悄然消失的.

如果字符串s1仍然是Python字节串(没有"u"前缀),则不会发生这种情况:

>>> s2 = 'asdf \n fdsa \x1d asdf'
>>> s2.splitlines()
['asdf ', ' fdsa \x1d asdf']
Run Code Online (Sandbox Code Playgroud)

我在参考https://docs.python.org/2.7/library/stdtypes.html#str.splitlines中找不到任何相关信息 .

为什么会这样?除"\ x1d"(或unichr(29))之外的其他字符会受到什么影响?

我在Ubuntu 12.04 LTS上使用Python 2.7.3.

Mar*_*ers 9

这确实没有记录; 我不得不仔细挖掘源代码才能找到它.

unicodetype_db.h文件将换行符定义为:

case 0x000A:
case 0x000B:
case 0x000C:
case 0x000D:
case 0x001C:
case 0x001D:
case 0x001E:
case 0x0085:
case 0x2028:
case 0x2029:
Run Code Online (Sandbox Code Playgroud)

这些是从Unicode数据库生成的 ; Unicode标准与所列出的任何编码点Line_Break属性设置为BK,CR,LFNL或双向类别设置为B(段落中断)被认为是一个换行符.

Unicode数据文件中,标准的第6版将U + 001D列为段落:

001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;
Run Code Online (Sandbox Code Playgroud)

(第5列是双向类别).

如果要限制要拆分的字符,可以使用正则表达式:

import re

linebreaks = re.compile(ur'[\n-\r\x85\u2028\u2929]')
linebreaks.split(yourtext)
Run Code Online (Sandbox Code Playgroud)

除了 U + 001C,U + 001D或U + 001E代码点之外,会将文本拆分为同一组换行符,因此三个数据结构控制字符.