কোনও স্ট্রিংকে একটি বৈধ ফাইলনামে পরিণত করবেন?


298

আমার কাছে একটি স্ট্রিং রয়েছে যা আমি একটি ফাইলের নাম হিসাবে ব্যবহার করতে চাই, তাই আমি পাইথন ব্যবহার করে সমস্ত অক্ষর মুছে ফেলতে চাই যা ফাইলের নামগুলিতে অনুমোদিত নয়।

আমি বরং অন্যথায় তুলনায় কঠোর হব, সুতরাং আসুন আমি বলি যে আমি কেবল অক্ষর, সংখ্যা এবং অন্যান্য অক্ষরের একটি ছোট সেট বজায় রাখতে চাই "_-.() "। সবচেয়ে মার্জিত সমাধান কি?

একাধিক অপারেটিং সিস্টেমে ফাইলের নামটি বৈধ হওয়া দরকার (উইন্ডোজ, লিনাক্স এবং ম্যাক ওএস) - এটি আমার লাইব্রেরির একটি এমপি 3 ফাইল ফাইল নাম হিসাবে গানের শিরোনাম সহ 3 টি মেশিনের মধ্যে ভাগ করে নেওয়া এবং ব্যাক আপ করা হয়।


17
এটিকে os.path মডিউলটিতে তৈরি করা উচিত নয়?
এন্ডোলিথ

2
সম্ভবত, যদিও তার ব্যবহারের ক্ষেত্রে একটি একক পথের প্রয়োজন হবে যা কেবল সমস্ত প্ল্যাটফর্ম জুড়েই নিরাপদ , কেবল বর্তমানের পথ নয়, যা ওএস.পথ হ্যান্ডেল করার জন্য ডিজাইন করা হয়নি।
jawawizard

2
উপরের মন্তব্যটি প্রসারিত করার জন্য: বর্তমানের নকশাটি os.pathওএসের উপর নির্ভর করে একটি ভিন্ন লাইব্রেরি লোড করে ( ডকুমেন্টেশনের দ্বিতীয় নোটটি দেখুন )। সুতরাং যদি কোনও উদ্ধৃতি ফাংশন os.pathএটিতে প্রয়োগ করা হয় তবে পসিক্স সিস্টেমে চলাকালীন উইন্ডোজ-সুরক্ষার জন্য উইন্ডোতে চলার সময় কেবল পসিক্স-সুরক্ষার জন্য স্ট্রিংটি উদ্ধৃত করতে পারে। ফলস্বরূপ ফাইলের নামটি উইন্ডোজ এবং পসআইএক্স উভয় ক্ষেত্রেই বৈধ হবে না, যা প্রশ্নটি জিজ্ঞাসা করে।
শেফার্ড

উত্তর:


164

তারা যেভাবে স্বেচ্ছাসেবী পাঠ্য থেকে "স্লাগ" তৈরি করে তার জন্য আপনি জাজানো ফ্রেমওয়ার্কটি দেখতে পারেন। একটি স্লাগ হ'ল ইউআরএল - এবং ফাইলের নাম বান্ধব।

জ্যাঙ্গো পাঠ্য কোনও ফাংশনকে সংজ্ঞায়িত করে slugify(), এটি সম্ভবত এই জাতীয় জিনিসের জন্য সোনার মান। মূলত, তাদের কোডটি নিম্নলিখিত।

def slugify(value):
    """
    Normalizes string, converts to lowercase, removes non-alpha characters,
    and converts spaces to hyphens.
    """
    import unicodedata
    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
    value = unicode(re.sub('[-\s]+', '-', value))
    # ...
    return value

আরও কিছু আছে, তবে আমি এটিকে ছেড়ে দিয়েছি, কারণ এটি স্লুগিফিকেশনকে সম্বোধন করে না, তবে পালাচ্ছে।


11
শেষ লাইনটি হওয়া উচিত: মান = ইউনিকোড (পুনঃসুব ('[- \ s] +', '-', মান))
জোসেফ তুরিয়ান

1
ধন্যবাদ - আমি কিছু মিস করতে পারি তবে আমি পাচ্ছি: "নরমালাইজ () যুক্তি 2 টি ইউনিকোড হতে হবে, স্ট্র নয়"
অ্যালেক্স কুক

"() যুক্তি 2 স্বাভাবিক করুন"। মানে value। যদি মানটি অবশ্যই ইউনিকোডের হয় তবে আপনার অবশ্যই নিশ্চিত হওয়া উচিত যে এটি আসলে ইউনিকোড। অথবা। যদি আপনার আসল মানটি আসলে ASCII স্ট্রিং হয় তবে আপনি ইউনিকোডের নরমালাইজেশনটি ছেড়ে যেতে চাইতে পারেন।
এস .লট

8
যদি কেউ এই পদ্ধতির ইতিবাচক দিকটি লক্ষ্য না করে তবে তা হ'ল এটি কেবল অ-আলফা অক্ষরগুলি সরিয়ে দেয় না, তবে প্রথমে ভাল বিকল্পগুলি খুঁজে পাওয়ার চেষ্টা করে (এনএফকেডি সাধারণীকরণের মাধ্যমে), তাই e ই হয়ে যায়, একটি সুপারস্ক্রিপ্ট 1 হয়ে যায় স্বাভাবিক 1, ইত্যাদি ধন্যবাদ
মাইকেল স্কট কুথবার্ট

48
slugifyফাংশন সরানো হয়েছে থেকে জ্যাঙ্গো / utils / text.py , এবং যে ফাইল একটি রয়েছে get_valid_filenameফাংশন।
ডেনিলসন সা মাইয়া

104

এই শ্বেত তালিকাটি (যেমন বৈধ_চরগুলিতে উপস্থিত অক্ষরের অনুমতি দেয়) কাজ করবে যদি অবৈধ (যেমন "..") এর ফাইলগুলির বিন্যাস বা বৈধ অক্ষরের সংমিশ্রণের সীমা না থাকে তবে উদাহরণস্বরূপ, আপনি যা বলেন "। txt" নামক একটি ফাইল নাম অনুমতি দেবে যা আমি মনে করি উইন্ডোজে বৈধ নয়। যেহেতু এটি সবচেয়ে সহজ পদ্ধিতি হ'ল আমি বৈধ_চার্স থেকে হোয়াইটস্পেস সরিয়ে ফেলার চেষ্টা করেছি এবং ত্রুটির ক্ষেত্রে একটি পরিচিত বৈধ স্ট্রিং প্রস্তুত করতে চাইছি, অন্য কোনও পদ্ধতির জানতে হবে উইন্ডোজ ফাইলের নামকরণের সীমাবদ্ধতাগুলি মোকাবেলা করার জন্য কোথায় কী অনুমতি দেওয়া হবে এবং এইভাবে আরও অনেক জটিল।

>>> import string
>>> valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
>>> valid_chars
'-_.() abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
>>> filename = "This Is a (valid) - filename%$&$ .txt"
>>> ''.join(c for c in filename if c in valid_chars)
'This Is a (valid) - filename .txt'

7
valid_chars = frozenset(valid_chars)আঘাত করবে না এটি যদি আলেচারগুলিতে প্রয়োগ হয় তবে এটি 1.5 গুণ বেশি দ্রুত।
jfs

2
সতর্কতা: এটি একই স্ট্রিংয়ের জন্য দুটি পৃথক স্ট্রিং মানচিত্র >>> আমদানি স্ট্রিং >>> বৈধ_চর্স = "- । ()% S% s"% (স্ট্রিং.এসসিআই_লেটারস, স্ট্রিং.ডিজিটস) >>> বৈধ_চার্স - ()) abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 '>>> ফাইলের নাম = "a.com/hello/world" >>>' '.জাইন (সি এর জন্য সি এর জন্য সিলে বৈধ_চার্স)' a.comheelorld 'a> ফাইল নাম = " ">>> '' .জাইন (ফাইলের নাম সি এর জন্য সিলে বৈধ_চর) 'a.comhelloworld' >>>
রবার্ট কিং

3
"CON"উইন্ডোজে কোনও ফাইলের নামকরণ আপনাকে সমস্যার মধ্যে ফেলবে তা উল্লেখ না করে ...
নাথান ওসমান

2
সামান্য পুনঃব্যবস্থা একটি বিকল্প চরিত্রকে সোজা করে নির্দিষ্ট করে তোলে। প্রথমে মূল কার্যকারিতা: '' .জাইন (ফাইলের নাম সি এর জন্য বৈধ_চরগুলিতে সি '') বা প্রতিটি অবৈধ চরিত্রের জন্য বিকল্প চরিত্র বা স্ট্রিং সহ: '' .জাইন (সি যদি বৈধ_চার্সে সি থাকে তবে '।') ফাইলের নাম সি)
পিটারভেরমন্ট

101

আপনি স্ট্রিং পদ্ধতিগুলির সাথে তালিকার বোঝাপড়া একসাথে ব্যবহার করতে পারেন।

>>> s
'foo-bar#baz?qux@127/\\9]'
>>> "".join(x for x in s if x.isalnum())
'foobarbazqux1279'

3
মনে রাখবেন আপনি বর্গাকার বন্ধনী বাদ দিতে পারেন। এই ক্ষেত্রে একটি জেনারেটর এক্সপ্রেশন যোগদানের জন্য পাস করা হয়, যা অন্যথায় অব্যবহৃত তালিকা তৈরির পদক্ষেপ সংরক্ষণ করে।
ওবেন সোনে

31
এটি পছন্দ করেছে সামান্য পরিবর্তন আমি করেছি: "" .জিন ([x যদি x.selnum () অন্য "_" এক্স এর জন্য x]) - এর ফলে এমন ফল পাওয়া যাবে যেখানে অবৈধ আইটেমগুলি ফাঁকা থাকার মতো _ are অন্য কাউকে থপ্পস দেয়।
এডি পার্কার

12
এই সমাধান মহান! যদিও আমি কিছুটা পরিবর্তন করেছি:filename = "".join(i for i in s if i not in "\/:*?<>|")
অ্যালেক্স ক্রিকেক

1
দুর্ভাগ্যক্রমে এটি স্পেস এবং বিন্দুগুলিকেও অনুমতি দেয় না তবে আমি ধারণাটি পছন্দ করি।
টিকটক

9
@tiktak: (এছাড়াও) ফাঁকা স্থান, বিন্দু এবং আন্ডারস্কোরগুলিতে আপনি যেতে পারেন"".join( x for x in s if (x.isalnum() or x in "._- "))
হার্ডমথ

95

ফাইলের নাম হিসাবে স্ট্রিংগুলি ব্যবহার করার কারণ কী? মানুষের পাঠযোগ্যতা যদি ফ্যাক্টর না হয় তবে আমি বেস 64 মডিউলটি দিয়ে যাব যা ফাইল সিস্টেম নিরাপদ স্ট্রিং উত্পাদন করতে পারে। এটি পঠনযোগ্য হবে না তবে আপনাকে সংঘর্ষের মোকাবেলা করতে হবে না এবং এটি বিপরীত।

import base64
file_name_string = base64.urlsafe_b64encode(your_string)

আপডেট : ম্যাথু মন্তব্যের ভিত্তিতে পরিবর্তন করা হয়েছে।


1
অবশ্যই যদি এটি হয় তবে এটি সেরা উত্তর answer
ব্যবহারকারী32141

60
সতর্কবাণী! ডিফল্টরূপে বেস 64 এনকোডিংয়ে বৈধ আউটপুট হিসাবে "/" অক্ষর অন্তর্ভুক্ত যা প্রচুর সিস্টেমে ফাইলের নামগুলিতে বৈধ নয়। পরিবর্তে বেস 64 ব্যবহার করুন urআরলাসেফ_ বি 64 ইনকোড (আপনার_স্তর)
ম্যাথু

15
প্রকৃতপক্ষে মানব পাঠযোগ্যতা প্রায় সবসময় একটি উপাদান, এমনকি যদি ডিবাগিংয়ের উদ্দেশ্যেও হয়।
স্থির_আরত্তি

5
পাইথন 3 এ কাজ করার জন্য your_stringবাইট অ্যারে বা ফলাফল হওয়া দরকার encode('ascii')
নুমেনন

4
def url2filename(url): url = url.encode('UTF-8') return base64.urlsafe_b64encode(url).decode('UTF-8') def filename2url(f): return base64.urlsafe_b64decode(f).decode('UTF-8')
জেফপ্রড

40

কেবল জিনিসগুলিকে আরও জটিল করার জন্য, কেবলমাত্র অবৈধ অক্ষরগুলি সরিয়ে আপনার বৈধ ফাইল নাম পাওয়ার নিশ্চয়তা নেই। যেহেতু অনুমোদিত ফাইলগুলি বিভিন্ন ফাইলের নামগুলিতে পৃথক হয়, তাই একটি রক্ষণশীল পদ্ধতির অবধি কোনও বৈধ নামটিকে অবৈধ নামে রূপান্তর করতে পারে। আপনি কেসগুলির জন্য বিশেষ হ্যান্ডলিং যুক্ত করতে চাইতে পারেন যেখানে:

  • স্ট্রিংটি সমস্ত অবৈধ অক্ষর (আপনাকে একটি খালি স্ট্রিং রেখে)

  • আপনি একটি বিশেষ অর্থ সহ একটি স্ট্রিং শেষ করবেন, যেমন "।" বা ".."

  • উইন্ডোগুলিতে, নির্দিষ্ট ডিভাইসের নামগুলি সংরক্ষিত থাকে। উদাহরণস্বরূপ, আপনি "nul", "nul.txt" (বা বাস্তবে কোনও কিছুই নয়) নামে একটি ফাইল তৈরি করতে পারবেন না সংরক্ষিত নামগুলি হ'ল:

    কন, পিআরএন, এউএক্স, এনএল, সিওএম 1, সিওএম 2, সিওএম 3, সিওএম 4, সিওএম 5, সিওএম 6, সিওএম 7, সিওএম 8, সিওএম 9, এলপিটি 1, এলপিটি 2, এলপিটি 3, এলপিটি 4, এলপিটি 8, এবং এলপিটি 9

ফাইল নামগুলিতে কিছু স্ট্রিং প্রিপেন্ড করে আপনি সম্ভবত এই বিষয়গুলি নিয়ে কাজ করতে পারেন যার ফলস্বরূপ কখনই এর একটিরও হতে পারে না এবং অবৈধ অক্ষরগুলি কেড়ে নিতে পারে।


24

পাইথন-স্লুগিফাই নামে গিথুবতে একটি দুর্দান্ত প্রকল্প রয়েছে :

ইনস্টল করুন:

pip install python-slugify

তারপরে ব্যবহার করুন:

>>> from slugify import slugify
>>> txt = "This\ is/ a%#$ test ---"
>>> slugify(txt)
'this-is-a-test'

2
আমি এই লাইব্রেরিটি পছন্দ করি তবে এটি যেমনটি ভেবেছিলাম তেমন ভাল নয়। প্রাথমিক পরীক্ষা ঠিক আছে তবে এটি বিন্দুকেও রূপান্তর করে। সুতরাং test.txtপায় test-txtযা অনেক বেশি।
therealmarv

23

এস.লোট উত্তর দেওয়ার মতোই , তারা কীভাবে কোনও স্ট্রিংকে একটি বৈধ ফাইলনামে রূপান্তর করতে পারে সে জন্য আপনি জ্যাঙ্গো ফ্রেমওয়ার্কটি দেখতে পারেন ।

সর্বাধিক সাম্প্রতিকতম এবং আপডেট হওয়া সংস্করণটি ইউটিস / টেক্সট.পিতে পাওয়া যায় এবং "get_ માન્ય_filename" সংজ্ঞায়িত করে যা নীচে:

def get_valid_filename(s):
    s = str(s).strip().replace(' ', '_')
    return re.sub(r'(?u)[^-\w.]', '', s)

( Https://github.com/django/django/blob/master/django/utils/text.py দেখুন )


4
ইতোমধ্যে django.utils.text import get_valid_filename
জ্যাঙ্গোতে

2
আপনি যদি রেজেক্সের সাথে অপরিচিত হন তবে re.sub(r'(?u)[^-\w.]', '', s)সমস্ত অক্ষর সরিয়ে ফেলুন যা অক্ষর নয়, সংখ্যা নয় (0-9), আন্ডারস্কোর ('_') নয়, ড্যাশ ('-') নয়, এবং সময়কাল (') নয়।' )। "চিঠিগুলি" এখানে ইউনিকোডের সমস্ত অক্ষর, যেমন includes অন্তর্ভুক্ত করে 漢語
কাপলিনেটর

3
আপনি দৈর্ঘ্যের জন্যও পরীক্ষা করতে চাইতে পারেন: ফাইলের নামগুলি 255 টি অক্ষরের মধ্যে সীমাবদ্ধ (বা আপনি জানেন 32; এফএসের উপর নির্ভর করে)
ম্যাথিয়াস উইঙ্কেলম্যান

19

এই সমাধানটি আমি শেষ পর্যন্ত ব্যবহার করেছি:

import unicodedata

validFilenameChars = "-_.() %s%s" % (string.ascii_letters, string.digits)

def removeDisallowedFilenameChars(filename):
    cleanedFilename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore')
    return ''.join(c for c in cleanedFilename if c in validFilenameChars)

ইউনিকোডেটা.অনর্মালাইজ কল উচ্চারণযুক্ত অক্ষরগুলিকে অচেনা সমতুল্যের সাথে প্রতিস্থাপন করে, যা কেবল এগুলি ছিটানোর চেয়ে আরও ভাল। এর পরে সমস্ত অননুমোদিত অক্ষর মুছে ফেলা হয়।

আমার দ্রবণটি সম্ভাব্য অস্বীকৃত ফাইলের নামগুলি এড়ানোর জন্য একটি জ্ঞাত স্ট্রিংকে পূর্বে নষ্ট করে না, কারণ আমি জানি যে আমার নির্দিষ্ট ফাইল নাম ফর্ম্যাটটি দিয়ে সেগুলি ঘটতে পারে না। আরও সাধারণ সমাধান করা দরকার।


আপনার অনন্য উপসর্গটির জন্য আপনি uuid.uuid4 () ব্যবহার করতে সক্ষম হবেন
এসএফ

6
উটের কেস .. আহ
বিকৃত হেজহোগ

পাইথন ৩.6 এর সাথে কাজ করার জন্য এটি সম্পাদনা / আপডেট করা যেতে পারে?
ওয়েভসাইলর

13

মনে রাখবেন, প্রকৃতপক্ষে ইউনিক্স সিস্টেমে ফাইলের নামগুলিতে কোনও বিধিনিষেধ নেই

  • এটিতে \ 0 থাকতে পারে না
  • এতে থাকতে পারে না /

অন্য সব কিছুই মেলা খেলা।

"স্পর্শ"
> এমনকি বহু লাইন
> হা হা
> ^ [[৩১ মি লাল লাল ^ [[0 মি
> অশুভ "
s ls -la 
-আরআর-আর - r-- 0 নভেম্বর 17 23:39? এমনকি বহু বহুরেখা? হাহা ?? [31 মিঃ লাল? [0 মি? মন্দ
s এলএস -লাব
-আরআর-আর - r-- 0 নভেম্বর 17 23:39 ven নেভেন \ মাল্টলাইন \ নহাহা \ n \ 033 [৩১ মিটার \ লাল \ \ 033 [0 মি \ নেভিল
আমার $ i (গ্লোব (q {./* এমনকি *})) এর জন্য l পার্ল -e '{মুদ্রণ $ i; } '
./
এমনকি বহু লাইন
হা হা
 লাল 
মন্দ

হ্যাঁ, আমি এএনএসআই রঙের কোডগুলি কেবল একটি ফাইলের নামে সংরক্ষণ করেছি এবং সেগুলি কার্যকর করতে পেরেছি।

বিনোদনের জন্য ডিরেক্টরি ডিরেক্টরিতে একটি বিএল চরিত্র রাখুন এবং মজাটি দেখুন যা আপনি এতে সিডি করবেন;)



1
@ কমলিনেটর যে আমার উত্তর পোস্ট হওয়ার 10 ঘন্টা পরে স্পষ্টতা যোগ করা হয়েছে :) ওপি'র সম্পাদনা লগ পরীক্ষা করে দেখুন।
কেন্ট ফ্রেড্রিক

12

এক লাইনে:

valid_file_name = re.sub('[^\w_.)( -]', '', any_string)

আপনি আরও পড়ার জন্য '_' অক্ষর রাখতে পারেন (উদাহরণস্বরূপ স্ল্যাশ প্রতিস্থাপনের ক্ষেত্রে)


7

"ফাইল লাইক" নয় এমন কোনও কিছু প্রতিস্থাপন করতে আপনি re.sub () পদ্ধতিটি ব্যবহার করতে পারেন। তবে বাস্তবে, প্রতিটি চরিত্র বৈধ হতে পারে; সুতরাং এটি সম্পন্ন করার জন্য কোনও প্রাক-বিল্ট ফাংশন নেই (আমি বিশ্বাস করি)।

import re

str = "File!name?.txt"
f = open(os.path.join("/tmp", re.sub('[^-a-zA-Z0-9_.() ]+', '', str))

/Tmp/filename.txt এ ফাইলহ্যান্ডেলের ফলাফল হবে।


5
গ্রুপ ম্যাচারে প্রথমে আপনাকে যেতে ড্যাশ দরকার তাই এটি কোনও ব্যাপ্তি হিসাবে উপস্থিত না হয়। re.sub ('[[^ - a-zA-Z0-9 _। ()] +', '', str)
ফোর্ড

7
>>> import string
>>> safechars = bytearray(('_-.()' + string.digits + string.ascii_letters).encode())
>>> allchars = bytearray(range(0x100))
>>> deletechars = bytearray(set(allchars) - set(safechars))
>>> filename = u'#ab\xa0c.$%.txt'
>>> safe_filename = filename.encode('ascii', 'ignore').translate(None, deletechars).decode()
>>> safe_filename
'abc..txt'

এটি খালি স্ট্রিং, বিশেষ ফাইলের নাম ('নুল', 'কন' ইত্যাদি) হ্যান্ডেল করে না।


অনুবাদ সারণীর জন্য +1, এটি এখন পর্যন্ত সবচেয়ে দক্ষ পদ্ধতি। বিশেষ ফাইলনাম / শূন্যপদের জন্য, একটি সাধারণ প্রাক-শর্ত পরীক্ষা করা যথেষ্ট এবং বহিরাগত সময়ের জন্য এটি একটি সাধারণ সংশোধনও।
ক্রিশ্চিয়ান উইটস

1
অনুবাদটি কোনও রেজিপেক্সের তুলনায় কিছুটা বেশি দক্ষ, সেই সময়টি সম্ভবত আপনি যদি ফাইলটি খোলার চেষ্টা করেন তবে সম্ভবত এটি দ্বিধাদ্বন্দ্বিত হবে যা কোনও সন্দেহ নেই যে আপনি কী করতে চাইছেন। সুতরাং আমি উপরের
জঞ্জালের

আমিও ব্ল্যাকলিস্ট নিয়ে চিন্তিত। মঞ্জুরিপ্রাপ্ত, এটি একটি কালো তালিকাভুক্ত যা একটি শ্বেত তালিকাভুক্ত, তবে এখনও। এটা কম মনে হয় ... নিরাপদ। আপনি কীভাবে জানেন যে "allchars" আসলে সম্পূর্ণ?
isaaclw

@ আইস্যাক্লিউ: '.ট্রান্সলেট ()' 256-চর স্ট্রিংটিকে অনুবাদ টেবিল হিসাবে স্বীকৃতি দেয় (বাইট-টু-বাইট অনুবাদ)। '.maketrans ()' এ জাতীয় স্ট্রিং তৈরি করে। সমস্ত মান আবৃত; এটি একটি খাঁটি শ্বেত তালিকা রয়েছে
jfs

ফাইলের নাম '।' (একটি বিন্দু) এটি ইউনিক্সে কাজ করবে না কারণ বর্তমান ডিরেক্টরিটি সেই নামটি ব্যবহার করছে।
ফিন অরুপ নীলসন

6

যদিও আপনাকে সাবধান হতে হবে। আপনি যদি কেবলমাত্র লাতিন ভাষার দিকে তাকাই থাকেন তবে এটি আপনার পরিচিতিতে স্পষ্টভাবে বলা হয়নি। কিছু শব্দ অর্থহীন বা অন্য অর্থ হয়ে উঠতে পারে যদি আপনি সেগুলি কেবলমাত্র অসি অক্ষর দিয়ে স্যানিট করেন।

কল্পনা করুন যে আপনার কাছে "ফরটি পোসি" রয়েছে (বনজ কবিতা), আপনার স্যানিটাইজেশন "ফোর্ট-পোজি" দিতে পারে (শক্তিশালী + অর্থহীন কিছু)

আপনার যদি চীনা চরিত্রগুলির সাথে ডিল করতে হয় তবে সবচেয়ে খারাপ W

"下 北 沢" আপনার সিস্টেমটি শেষ হতে পারে "---" যা কিছুক্ষণ পরে ব্যর্থ হবে এবং খুব সহায়ক নয়। সুতরাং আপনি যদি কেবলমাত্র ফাইলগুলির সাথে ডিল করেন তবে আমি তাদেরকে আপনার নিয়ন্ত্রণ করা জেনেরিক চেইন বলতে বা চরিত্রগুলি যেমন আছে তেমন রাখতে উত্সাহিত করব। ইউআরআইদের জন্য, প্রায় একই।


6

কেন কেবল চেষ্টা করে / বাদ দিয়ে "ওসোপেন" মুড়ে রাখবেন না এবং অন্তর্নিহিত ওএসটিকে ফাইলটি বৈধ কিনা তা বাছাই করতে দিন?

এটি অনেক কম কাজের মতো মনে হয় এবং আপনি কোন ওএস ব্যবহার করেন তা বৈধ।


5
এটি নামটি বৈধ কিনা? মানে, ওএস যদি খুশি না হয় তবে আপনার এখনও কিছু করা দরকার, তাই না?
jeromej

1
কিছু ক্ষেত্রে, ওএস / ল্যাঙ্গুয়েজ নিঃশব্দে আপনার ফাইলের নামটি একটি বিকল্প ফর্মে পরিণত করতে পারে, তবে আপনি যখন ডিরেক্টরি তালিকা করেন, আপনি আলাদা নামটি পেয়ে যাবেন। এবং এটি একটি "যখন আমি সেখানে ফাইলটি লিখি তখন বাড়ে, কিন্তু যখন আমি ফাইলটির সন্ধান করি তখন এটি অন্যরকম কিছু বলা হয়" সমস্যা। (আমি ভ্যাক্সে শুনেছি এমন আচরণের কথা বলছি ...)
কেন্ট ফ্রেড্রিক

তদতিরিক্ত, "একাধিক অপারেটিং সিস্টেমে ফাইলের নাম বৈধ হওয়া দরকার", যা আপনি osopenএকটি মেশিনে চলমান দিয়ে সনাক্ত করতে পারবেন না ।
লার্শ

5

অন্য মন্তব্যগুলি যা অন্যান্য মন্তব্যগুলি এখনও সম্বোধন করে না তা হ'ল খালি স্ট্রিং, যা সম্ভবত কোনও বৈধ ফাইলের নাম নয়। আপনি অনেকগুলি অক্ষর বাদ দিয়ে খালি স্ট্রিং দিয়েও শেষ করতে পারেন।

উইন্ডোজ সংরক্ষিত ফাইলের নাম এবং বিন্দু সংক্রান্ত সমস্যাগুলির সাথে কী হবে, এই প্রশ্নটির সবচেয়ে নিরাপদ উত্তর "আমি স্বেচ্ছাসেবীর ব্যবহারকারী ইনপুট থেকে কীভাবে একটি বৈধ ফাইল নামটি স্বাভাবিক করব?" হ'ল "এমনকি চেষ্টাও করবেন না": যদি আপনি এড়াতে অন্য কোনও উপায় খুঁজে পান (যেমন, ফাইলের নাম হিসাবে একটি ডাটাবেস থেকে পূর্ণসংখ্যার প্রাথমিক কীগুলি ব্যবহার করে), এটি করুন।

আপনার অবশ্যই যদি হয় এবং আপনার অবশ্যই ফাঁকা স্থান এবং '' এর অনুমতি দেওয়া দরকার। নামের অংশ হিসাবে ফাইল এক্সটেনশনের জন্য, এর মতো কিছু চেষ্টা করুন:

import re
badchars= re.compile(r'[^A-Za-z0-9_. ]+|^\.|\.$|^ | $|^$')
badnames= re.compile(r'(aux|com[1-9]|con|lpt[1-9]|prn)(\.|$)')

def makeName(s):
    name= badchars.sub('_', s)
    if badnames.match(name):
        name= '_'+name
    return name

এমনকি এটির গ্যারান্টি দেওয়া যায় না বিশেষত অপ্রত্যাশিত ওএসগুলিতে - উদাহরণস্বরূপ আরআইএসসি ওএস স্পেসগুলি এবং ব্যবহারগুলি ঘৃণা করে। ' ডিরেক্টরি বিভাজক হিসাবে।


4

আমি এখানে পাইথন-স্লুগিফাই অ্যাপ্রোচ পছন্দ করেছি তবে এটি বিন্দুগুলিও সরিয়ে দিচ্ছিল যা পছন্দসই ছিল না। সুতরাং আমি এইভাবে এস 3 এ একটি ক্লিন ফাইলনাম আপলোড করার জন্য এটি অপ্টিমাইজ করেছি:

pip install python-slugify

উদাহরণ কোড:

s = 'Very / Unsafe / file\nname hähä \n\r .txt'
clean_basename = slugify(os.path.splitext(s)[0])
clean_extension = slugify(os.path.splitext(s)[1][1:])
if clean_extension:
    clean_filename = '{}.{}'.format(clean_basename, clean_extension)
elif clean_basename:
    clean_filename = clean_basename
else:
    clean_filename = 'none' # only unclean characters

আউটপুট:

>>> clean_filename
'very-unsafe-file-name-haha.txt'

এটি এতটাই ব্যর্থতা, এটি এক্সটেনশন ছাড়াই ফাইলের সাথে কাজ করে এবং এটি কেবল অনিরাপদ অক্ষরের ফাইলের নামের জন্যও কাজ করে (ফলাফলটি noneএখানে)।


1
আমি এটি পছন্দ করি, চাকাটিকে পুনরায় উদ্ভাবন করবেন না, আপনার প্রয়োজন না হলে পুরো জ্যাঙ্গো কাঠামোটি আমদানি করবেন না, যদি আপনি ভবিষ্যতে এটি বজায় না রাখেন তবে সরাসরি কোডটি পেস্ট করবেন না, এবং উত্পন্ন স্ট্রিং চেষ্টা করে সুরক্ষিতদের সাথে একই রকমের অক্ষরের সাথে মেলে যাতে নতুন স্ট্রিং পড়া সহজ হয়।
ভিসেন্তেহের

1
ড্যাশের পরিবর্তে আন্ডারস্কোর ব্যবহার করতে হবে: নাম = স্লুগাইফাই (গুলি, বিভাজক = '_')
ভিসেনটিহেরের

3

পাইথন ৩.6-এর উত্তর পরিবর্তিত হয়েছে

import string
import unicodedata

validFilenameChars = "-_.() %s%s" % (string.ascii_letters, string.digits)
def removeDisallowedFilenameChars(filename):
    cleanedFilename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore')
    return ''.join(chr(c) for c in cleanedFilename if chr(c) in validFilenameChars)

আপনি কি আপনার উত্তর বিস্তারিতভাবে বলতে পারেন?
নির্মলতা

এটি একই উত্তরটি সোফি গেজ দ্বারা গৃহীত। তবে এটি অজগর 3.6 তে কাজ করার জন্য পরিবর্তন করা হয়েছে
জিন-রবিন

2

আমি বুঝতে পারি যে এখানে অনেক উত্তর রয়েছে তবে তারা বেশিরভাগই নিয়মিত অভিব্যক্তি বা বাহ্যিক মডিউলগুলিতে নির্ভর করে, তাই আমি আমার নিজের উত্তরটি ফেলে দিতে চাই। একটি খাঁটি পাইথন ফাংশন, কোনও বাহ্যিক মডিউল প্রয়োজন নেই, নিয়মিত প্রকাশ নেই। আমার পদ্ধতির অবৈধ অক্ষরগুলি পরিষ্কার করা নয়, কেবলমাত্র বৈধদের অনুমতি দেওয়া।

def normalizefilename(fn):
    validchars = "-_.() "
    out = ""
    for c in fn:
      if str.isalpha(c) or str.isdigit(c) or (c in validchars):
        out += c
      else:
        out += "_"
    return out    

আপনি যদি চান তবে আপনি নিজের বৈধ অক্ষরগুলিতে যুক্ত করতে পারেন validchars শুরুতে অক্ষরগুলি ভেরিয়েবলটিতে , যেমন আপনার জাতীয় বর্ণগুলি যা ইংরেজি বর্ণমালায় নেই। এটি এমন কিছু যা আপনি চাইতে পারেন বা নাও চান: কিছু ফাইল সিস্টেম যা ইউটিএফ -8 এ চালিত হয় না এখনও অ-এসসিআইআই অক্ষরগুলির সাথে সমস্যা হতে পারে।

এই ফাংশনটি একটি একক ফাইলের নামের বৈধতার জন্য পরীক্ষা করা, তাই এটি পাথ বিভাজককে তাদের অবৈধ অক্ষর বিবেচনা করে প্রতিস্থাপন করবে। আপনি যদি এটি যুক্ত করতে চান তবে ifওএস পাথ বিভাজককে অন্তর্ভুক্ত করার জন্য এটি সংশোধন করা তুচ্ছ ।


1

এই সমাধানগুলির বেশিরভাগই কাজ করে না।

'/ হ্যালো / ওয়ার্ল্ড' -> 'হেলিওরল্ড'

'/ হেলিওরল্ড' / -> 'হেলিওরল্ড'

এটি আপনি যা চান তা সাধারণভাবে নয়, বলুন আপনি প্রতিটি লিঙ্কের জন্য এইচটিএমএল সংরক্ষণ করছেন, আপনি আলাদা ওয়েবপৃষ্ঠার জন্য এইচটিএমএলটি ওভাররাইট করতে যাচ্ছেন।

আমি একটি ডিক বাছাই যেমন:

{'helloworld': 
    (
    {'/hello/world': 'helloworld', '/helloworld/': 'helloworld1'},
    2)
    }

2 পরবর্তী ফাইলনামে সংযুক্ত করা উচিত এমন নম্বরটি উপস্থাপন করে।

আমি প্রতিবার ডিক থেকে ফাইলের নামটি সন্ধান করি। যদি এটি না থাকে তবে আমি একটি নতুন তৈরি করব, প্রয়োজনে সর্বাধিক নম্বর সংযোজন করব।


মনে রাখবেন, হেলিওর্ল্ড 1 ব্যবহার করে, আপনারও পরীক্ষা করা উচিত হেলিওর্ল্ড 1 ব্যবহারে নেই এবং এমন কি ..
রবার্ট কিং

1

ওপি যা চেয়েছিল ঠিক তা নয় তবে এটি আমি ব্যবহার করি কারণ আমার অনন্য এবং বিপরীত রূপান্তর দরকার:

# p3 code
def safePath (url):
    return ''.join(map(lambda ch: chr(ch) if ch in safePath.chars else '%%%02x' % ch, url.encode('utf-8')))
safePath.chars = set(map(lambda x: ord(x), '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-_ .'))

ফলাফল "কিছুটা" পঠনযোগ্য, কমপক্ষে সিসাদমিন দৃষ্টিকোণ থেকে।


ফাইলগুলির নামের কোনও ফাঁকা স্থান নেই এর জন্য একটি মোড়ক:def safe_filename(filename): return safePath(filename.strip().replace(' ','_'))
স্পিডকোডার 5

1

আপনি যদি কোনও প্যাকেজ ইনস্টল করতে আপত্তি করেন না তবে এটি কার্যকর হবে: https://pypi.org/project/pathediaate/

Https://pypi.org/project/pathediaate/#sanitize-a-filename থেকে :

from pathvalidate import sanitize_filename

fname = "fi:l*e/p\"a?t>h|.t<xt"
print(f"{fname} -> {sanitize_filename(fname)}\n")
fname = "\0_a*b:c<d>e%f/(g)h+i_0.txt"
print(f"{fname} -> {sanitize_filename(fname)}\n")

আউটপুট

fi:l*e/p"a?t>h|.t<xt -> filepath.txt
_a*b:c<d>e%f/(g)h+i_0.txt -> _abcde%f(g)h+i_0.txt

0

আমি নিশ্চিত যে এটি দুর্দান্ত উত্তর নয়, যেহেতু এটি লুপিংয়ের স্ট্রিংটি পরিবর্তন করে তবে এটি ঠিকঠাকভাবে কাজ করে বলে মনে হচ্ছে:

import string
for chr in your_string:
 if chr == ' ':
   your_string = your_string.replace(' ', '_')
 elif chr not in string.ascii_letters or chr not in string.digits:
    your_string = your_string.replace(chr, '')

আমি "".join( x for x in s if (x.isalnum() or x in "._- "))এই পোস্টের মন্তব্যে এটি পেয়েছি
সেরজিওআরাউজো

0

হালনাগাদ

এই 6 বছরের পুরানো উত্তরে মেরামতের বাইরে সমস্ত লিঙ্কগুলি ভাঙা।

এছাড়াও, আমি এটি আর এইভাবে করব না, কেবল base64এনকোড করুন বা অনিরাপদ অক্ষরগুলি ফেলে দিন। পাইথন 3 উদাহরণ:

import re
t = re.compile("[a-zA-Z0-9.,_-]")
unsafe = "abc∂éåß®∆˚˙©¬ñ√ƒµ©∆∫ø"
safe = [ch for ch in unsafe if t.match(ch)]
# => 'abc'

সঙ্গে base64আপনি এনকোড এবং ডিকোড করতে পারেন, তাই আপনি আসল ফাইলের নাম আবার উদ্ধার করতে পারেন।

তবে ব্যবহারের ক্ষেত্রে নির্ভর করে আপনি এলোমেলো ফাইলের নাম তৈরি করা এবং আলাদা ফাইল বা ডিবিতে মেটাডেটা সঞ্চয় করা থেকে ভাল।

from random import choice
from string import ascii_lowercase, ascii_uppercase, digits
allowed_chr = ascii_lowercase + ascii_uppercase + digits

safe = ''.join([choice(allowed_chr) for _ in range(16)])
# => 'CYQ4JDKE9JfcRzAZ'

মৌলিক লিঙ্করোন্টেন উত্তর :

bobcatপ্রকল্পের একটি পাইথন মডিউল যে শুধু এই আছে ধারণ করে।

এটি সম্পূর্ণ দৃust় নয়, এই পোস্টটি এবং এই উত্তরটি দেখুন

সুতরাং, যেমনটি উল্লেখ করা হয়েছে: base64পঠনযোগ্যতা বিবেচনা না করলে এনকোডিং সম্ভবত একটি ভাল ধারণা।


সমস্ত লিঙ্ক মারা গেছে। মানুষ, কিছু কর
দ্য পিসফুল কোডার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.