2013-08-20 66 views
1

Triyng,使這個在Python 2.7:Python的unicode.splitlines()觸發的非EOL字符

>>> s = u"some\u2028text" 
>>> s 
u'some\u2028text' 
>>> l = s.splitlines(True) 
>>> l 
[u'some\u2028', u'text'] 

\u2028是左到右的嵌入字符,而不是\r\n,所以該行不應該被分割。有錯誤還是隻是我的誤解?

+2

'\ u2028'是'LINE SEPARATOR',左到右的嵌入是'\ u202A' –

+0

@帕維爾 - anossov謝謝。現在我打破了在Windows charmap中查找Unicode字符的習慣。 – Pehat

+0

有趣,我的charmap很好:http://i.imgur.com/jwkyMEm.png –

回答

5

\u2028是行分隔符,左到右的嵌入是\u202A

>>> import unicodedata 

>>> unicodedata.name(u'\u2028') 
'LINE SEPARATOR' 

>>> unicodedata.name(u'\u202A') 
'LEFT-TO-RIGHT EMBEDDING' 

碼點的名單被認爲換行符是容易的(不是那麼容易,雖然找到)在Python源看到( Python 2.7版,通過我的意見):

/* Returns 1 for Unicode characters having the line break 
* property 'BK', 'CR', 'LF' or 'NL' or having bidirectional 
* type 'B', 0 otherwise. 
*/ 
int _PyUnicode_IsLinebreak(register const Py_UNICODE ch) 
{ 
    switch (ch) { 
    // Basic Latin 
    case 0x000A: // LINE FEED 
    case 0x000B: // VERTICAL TABULATION 
    case 0x000C: // FORM FEED 
    case 0x000D: // CARRIAGE RETURN 
    case 0x001C: // FILE SEPARATOR 
    case 0x001D: // GROUP SEPARATOR 
    case 0x001E: // RECORD SEPARATOR 

    // Latin-1 Supplement 
    case 0x0085: // NEXT LINE 

    // General punctuation 
    case 0x2028: // LINE SEPARATOR 
    case 0x2029: // PARAGRAPH SEPARATOR 
     return 1; 
    } 
    return 0; 
} 
+0

謝謝你提到這個偉大的模塊。 – Pehat

2

U+2028LINE SEPARATORU+2028U+2029PARAGRAPH SEPARATOR應將視爲換行符,因此Python正在做正確的事情。

當然,在非標準的換行字符列表上拆分有時候是完全合理的。但是你不能用splitlines這樣做。您將不得不使用split - 如果您需要splitlines的附加功能,則必須自行實施。例如:

return [line.rstrip(sep) for line in s.split(sep)] 
+0

這筆交易是我使用使用'splitlines()'的'codecs'模塊。在我的情況下,更容易忽略來自輸入的一些垃圾字符,而不是編寫我自己的解析器。 – Pehat

+0

@Pehat:當你使用universal-newlines模式時,'codecs'使用'splitlines',它是一樣的:如果你想要一個非標準的換行符,你不能使用通用換行符。但是,取代'splitlines'情況並不容易...(作爲一個方面說明,不管你使用的是'codecs',你可能想強烈考慮使用'io'。) – abarnert