2012-03-18 8 views
15

ओएस एक्स और पायथन में यूनिकोड फ़ाइल नामों के साथ थोड़ा सा संघर्ष करना। मैं बाद में कोड में नियमित अभिव्यक्ति के लिए इनपुट के रूप में फ़ाइल नामों का उपयोग करने की कोशिश कर रहा हूं, लेकिन फ़ाइल नामों में उपयोग किया जाने वाला एन्कोडिंग sys.getfilesystemencoding() से अलग है। निम्नलिखित कोड डालें:मैक ओएस एक्स में फाइल सिस्टम के लिए यूनिकोड एन्कोडिंग पायथन में सही नहीं है?

#!/usr/bin/env python 
# coding=utf-8 

import sys,os 
print sys.getfilesystemencoding() 

p = u'/temp/s/' 
s = u'åäö' 
print 's', [ord(c) for c in s], s 
s2 = s.encode(sys.getfilesystemencoding()) 
print 's2', [ord(c) for c in s2], s2 
os.mkdir(p+s) 
for d in os.listdir(p): 
    print 'dir', [ord(c) for c in d], d 

यह निम्न आउटपुट:

utf-8 
s [229, 228, 246] åäö 
s2 [195, 165, 195, 164, 195, 182] åäö 
dir [97, 778, 97, 776, 111, 776] åäö 

तो, फाइल सिस्टम एनकोडिंग utf-8 है, लेकिन जब मैं उस का उपयोग कर आओ मेरी फ़ाइल नाम सांकेतिक शब्दों में बदलना, यह एक ही नहीं होगा जैसे कि मैं एक ही स्ट्रिंग के साथ एक डीआईआर नाम बनाते हैं। मैं उम्मीद करता हूं कि जब मैं एक डीआईआर बनाने के लिए अपनी स्ट्रिंग का उपयोग करता हूं, और इसे वापस नाम पढ़ता हूं, तो उसे उसी कोड का उपयोग करना चाहिए जैसे कि मैंने सीधे एन्कोडिंग लागू की हो।

यदि हम कोड अंक 97, 778, 9 7, 776, 111, 776 पर देखते हैं, तो यह मूल रूप से अतिरिक्त डाइक्रिटिक के साथ ASCII वर्ण हैं, उदा। ओ + ¨ = ö, जो इसे दो अक्षर बनाता है, एक नहीं। मैं इस विसंगति से कैसे बच सकता हूं, क्या पाइथन में एक एन्कोडिंग योजना है जो ओएस एक्स द्वारा इस व्यवहार से मेल खाती है, और मुझे सही परिणाम देने के लिए getfilesystemencoding() क्यों नहीं मिलता है?

या क्या मैंने गड़बड़ की है?

+0

समस्या उन विशिष्ट पात्रों के लिए हल किया जा सकता, ऐसा करके फ़ाइल नामकरण स्ट्रिंग्स पर रेगेक्सपी को डायक्रिटिक-कम यूनिकोड में लाने के लिए: 'm_aa = re.compile (ur "a \ u0308", re.I), m_ae = re.compile (ur "a \ u030a", re.I) , m_oe = re.compile (ur "o \ u0308", re.I) – RipperDoc

उत्तर

24

मैकोज़ एक्स फ़ाइल नामों को स्टोर करने के लिए एक विशेष प्रकार के विघटित यूटीएफ -8 का उपयोग करता है। यदि आपको उदा। यहाँ से

filename = unicodedata.normalize('NFC', unicode(filename, 'utf-8')).encode('utf-8') 

: फ़ाइल नाम में पढ़ सकते हैं और उन्हें एक "सामान्य" UTF-8 फ़ाइल पर लिखने, तो आप उन्हें सामान्य चाहिए https://web.archive.org/web/20120423075412/http://boodebr.org/main/python/all-about-python-and-unicode

+0

node.js के साथ इस समस्या में भाग लें npm पैकेज 'unorm' के लिए वास्तव में एक अच्छा इंटरफ़ेस है। – mmilleruva

17

getfilesystemencoding() आप सही जवाब दे रहा है (एन्कोडिंग), लेकिन यह आपको unicode normalisation form नहीं बताता है।

विशेष रूप से, एचएफएस + फाइल सिस्टम यूटीएफ -8 एन्कोडिंग का उपयोग करता है, और "डी" के करीब एक सामान्यीकरण फॉर्म (जिसमें ö जैसे रचनाकृत वर्णों की आवश्यकता होती है ताकि में विघटित हो सके)। एचएफएस + सामान्यीकरण फॉर्म से भी जुड़ा हुआ है क्योंकि यह यूनिकोड संस्करण 3.2 में मौजूद है-जैसा कि ऐप्पल के documentation for the HFS+ format में विस्तृत है।

पायथन के unicodedata.normalize विधि रूपों के बीच धर्मान्तरित, और यदि आप ucd_3_2_0 वस्तु के साथ कॉल उपसर्ग, आप इसे यूनिकोड संस्करण 3.2 के लिए विवश कर सकते हैं:

filename = unicodedata.ucd_3_2_0.normalize('NFC', unicode(filename, 'utf-8')).encode('utf-8') 
+0

धन्यवाद, महान जवाब, इच्छा है कि मैं दोनों उत्तरों को ऊपर उठा सकूं और स्वीकार कर सकूं! – RipperDoc

+2

दरअसल, यह काफी एनएफडी नहीं है, लेकिन यह करीब है। – tchrist

संबंधित मुद्दे