পথ এবং ফাইলের নামগুলি থেকে কীভাবে অবৈধ অক্ষরগুলি সরিয়ে ফেলা যায়?


456

সরল স্ট্রিং থেকে অবৈধ পথ এবং অক্ষর ফাইল করার জন্য আমার একটি শক্ত ও সহজ উপায় দরকার need আমি নীচের কোডটি ব্যবহার করেছি তবে এটি কিছু করার মতো বলে মনে হচ্ছে না, আমি কী মিস করছি?

using System;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string illegal = "\"M<>\"\\a/ry/ h**ad:>> a\\/:*?\"<>| li*tt|le|| la\"mb.?";

            illegal = illegal.Trim(Path.GetInvalidFileNameChars());
            illegal = illegal.Trim(Path.GetInvalidPathChars());

            Console.WriteLine(illegal);
            Console.ReadLine();
        }
    }
}

1
ট্রিম স্ট্রিংগুলির শুরু এবং শেষ থেকে অক্ষরগুলি সরিয়ে দেয়। তবে, আপনার সম্ভবত জিজ্ঞাসা করা উচিত কেন ডেটাটি অবৈধ, এবং চেষ্টা করে এবং স্যানিটাইজ / ফিক্স করার চেয়ে ডেটা প্রত্যাখ্যান করে।
user7116

8
ইউনিক্স শৈলীর নামগুলি উইন্ডোজটিতে বৈধ নয় এবং আমি 8.3 সংক্ষিপ্ত নামের সাথে ডিল করতে চাই না।
গ্যারি উইলফোবি

GetInvalidFileNameChars()ফোল্ডার পাথ থেকে like ইত্যাদির মতো জিনিসগুলি ছাঁটাবে।
সিএডি

1
Path.GetInvalidPathChars()ফালা লাগে না *বা?
সিএডি ব্লোক

18
আমি এই প্রশ্নের পাঁচটি উত্তর পরীক্ষা করেছি (100,000 এর সময়সীমা লুপ) এবং নিম্নলিখিত পদ্ধতিটি দ্রুততম। নিয়মিত প্রকাশটি ২ য় স্থান নিয়েছিল এবং এটি 25% ধীর ছিল: পাবলিক স্ট্রিং গেটসফেইফিলনাম (স্ট্রিং ফাইলের নাম) {রিটার্ন স্ট্রিং oinজাইন ("_", ফাইলের নাম Sস্প্লিট (পাথ.গেটইনওল্ডফিলনেমচার্স ())); }
Brain2000

উত্তর:


494

পরিবর্তে এই জাতীয় কিছু চেষ্টা করুন;

string illegal = "\"M\"\\a/ry/ h**ad:>> a\\/:*?\"| li*tt|le|| la\"mb.?";
string invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());

foreach (char c in invalid)
{
    illegal = illegal.Replace(c.ToString(), ""); 
}

তবে আমাকে এই মন্তব্যে একমত হতে হবে, আমি সম্ভবত অবৈধ পথের বৈধ কিন্তু সম্ভবত অনিচ্ছাকৃত পথে প্রবেশের চেষ্টা না করে অবৈধ পথের উত্স নিয়ে কাজ করার চেষ্টা করব।

সম্পাদনা করুন: বা একটি সম্ভাব্য 'আরও ভাল' সমাধান, রিজেক্স ব্যবহার করে।

string illegal = "\"M\"\\a/ry/ h**ad:>> a\\/:*?\"| li*tt|le|| la\"mb.?";
string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
Regex r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
illegal = r.Replace(illegal, "");

তবুও, প্রশ্নটি জিজ্ঞাসা করা হবে, আপনি কেন প্রথম স্থানে এটি করছেন।


40
দুটি তালিকা একসাথে যুক্ত করার প্রয়োজন নেই। অবৈধ ফাইল নাম চর তালিকায় অবৈধ পথের চর তালিকা রয়েছে এবং আরও কয়েকটি রয়েছে। এখানে অন্তর্ভুক্ত দুটি তালিকার তালিকা রয়েছে: 34,60,62,124,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,58,42,63,92,47 34,60,62,124,0,1,2 , 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 28 28,29,30,31
সেরেল বোথা

9
@ এসজেবোথা এটি উইন্ডোজ এবং মাইক্রোসফ্টের .NET প্রয়োগের ক্ষেত্রে সত্য হতে পারে আমি মনো চালিত লিনাক্স বলতে একই ধারণা গ্রহণ করতে রাজি নই।
ম্যাথু শার্লে

7
প্রথম সমাধান সম্পর্কে। স্ট্রিং অ্যাসাইনমেন্টের চেয়ে স্ট্রিংবিল্ডারটি আরও দক্ষ হওয়া উচিত নয়?
এপিগনোসেক্স

6
এর মুল্যটির জন্য, @ ম্যাথিউশার্লি, গেটইনুয়ালিডপ্যাথচার্স () এর মনো বাস্তবায়ন কেবল 0x00 দেয় এবং উইন্ডোজবিহীন প্ল্যাটফর্মগুলিতে চলার সময় কেবল 0x00 এবং '/' প্রদান করে। উইন্ডোজে, অবৈধ অক্ষরের তালিকাগুলি অনেক দীর্ঘ এবং গেটআইনুডিয়ালিপ্যাথচারস () সম্পূর্ণরূপে গেটআইনুডিয়ালিফিলনামচার্স () এর মধ্যে নকল হয়। এটি দুর্দশাগ্রস্ত ভবিষ্যতে কোনও পরিবর্তন ঘটবে না, সুতরাং আপনি যা করছেন তা সত্যিই এই ফাংশনটি চালানোর সময় দ্বিগুণ করছে কারণ আপনি শঙ্কিত যে কোনও বৈধ পথের সংজ্ঞা শীঘ্রই পরিবর্তিত হবে। যা তা করবে না।
ওয়ারেন রুমাক

13
@ চারলেহ এই আলোচনাটি এতটাই অপ্রয়োজনীয় ... কোডটি সর্বদা অপ্টিমাইজ করা উচিত এবং এর ভুল হওয়ার কোনও ঝুঁকি নেই। একটি ফাইল নামও পথের একটি অংশ। সুতরাং এটি কেবল অযৌক্তিক যে GetInvalidPathChars()এমন অক্ষরগুলি থাকতে পারে যা GetInvalidFileNameChars()না পারে। আপনি "অকাল" অপ্টিমাইজেশনের উপর সঠিকতা নিচ্ছেন না। আপনি কেবল খারাপ কোড ব্যবহার করছেন।
স্টিফান ফ্যাবিয়ান

352

মূল প্রশ্নটি "অবৈধ চরিত্রগুলি অপসারণ" করতে বলা হয়েছিল:

public string RemoveInvalidChars(string filename)
{
    return string.Concat(filename.Split(Path.GetInvalidFileNameChars()));
}

পরিবর্তে আপনি সেগুলি প্রতিস্থাপন করতে চাইতে পারেন:

public string ReplaceInvalidChars(string filename)
{
    return string.Join("_", filename.Split(Path.GetInvalidFileNameChars()));    
}

এই উত্তরটি সেরেসের অন্য থ্রেডে ছিল , আমি সত্যিই এটি পরিষ্কার এবং সহজ পছন্দ করি।


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

35
আমি এই প্রশ্নটি থেকে পাঁচটি পদ্ধতি পরীক্ষা করেছি (100,000 এর টাইম লুপ) এবং এই পদ্ধতিটি দ্রুততম। নিয়মিত প্রকাশটি ২ য় স্থান নিয়েছিল এবং এই পদ্ধতির চেয়ে 25% ধীর ছিল।
Brain2000

10
ঠিকানার সাথে @BH এর মন্তব্যে, কেবল এক string.Concat (name.Split (Path.GetInvalidFileNameChars ())) ব্যবহার করতে পারেন
মাইকেল সাটন

210

আমি ফাইলের নামগুলি পরিষ্কার করতে লিনক ব্যবহার করি। বৈধ পাথগুলিও পরীক্ষা করতে আপনি সহজেই এটি প্রসারিত করতে পারেন।

private static string CleanFileName(string fileName)
{
    return Path.GetInvalidFileNameChars().Aggregate(fileName, (current, c) => current.Replace(c.ToString(), string.Empty));
}

হালনাগাদ

কিছু মন্তব্য নির্দেশ করে যে এই পদ্ধতিটি তাদের পক্ষে কাজ করছে না তাই আমি একটি ডটনেটফিডাল স্নিপেটের একটি লিঙ্ক অন্তর্ভুক্ত করেছি যাতে আপনি পদ্ধতিটি বৈধতা দিতে পারেন।

https://dotnetfiddle.net/nw1SWY


4
এটি আমার পক্ষে কার্যকর হয়নি। পদ্ধতিটি পরিষ্কার স্ট্রিংটি ফিরিয়ে দিচ্ছে না। এটি পাস করা ফাইলের নামটি যেমনটি ফিরিয়ে দিচ্ছে।
করণ

@ করণ যা বলেছিল, এটি কাজ করে না, মূল স্ট্রিং ফিরে আসে।
জন

আপনি আসলে এই যদিও মত Linq সঙ্গে এই কাজ করতে পারেন: var invalid = new HashSet<char>(Path.GetInvalidPathChars()); return new string(originalString.Where(s => !invalid.Contains(s)).ToArray())। পারফরম্যান্স সম্ভবত দুর্দান্ত নয় তবে সম্ভবত এটি কোনও বিষয় নয়।
কেসি

2
@ করণ বা জোন আপনি এই ফাংশনটি কী ইনপুট প্রেরণ করছেন? এই পদ্ধতির যাচাইয়ের জন্য আমার সম্পাদনা দেখুন।
মাইকেল মিন্টন

3
এটি সহজ - ছেলেরা বৈধ অক্ষরের সাথে স্ট্রিংগুলি পার করছিল। শীতল সমষ্টিগত সমাধানের জন্য উত্সাহিত।
নিকমাভিচ

89

আপনি এই জাতীয় লিঙ্ক ব্যবহার করে অবৈধ অক্ষর মুছে ফেলতে পারেন:

var invalidChars = Path.GetInvalidFileNameChars();

var invalidCharsRemoved = stringWithInvalidChars
.Where(x => !invalidChars.Contains(x))
.ToArray();

সম্পাদনা
করুন মন্তব্যগুলিতে উল্লিখিত প্রয়োজনীয় সম্পাদনার সাথে এটি দেখতে কেমন লাগে:

var invalidChars = Path.GetInvalidFileNameChars();

string invalidCharsRemoved = new string(stringWithInvalidChars
  .Where(x => !invalidChars.Contains(x))
  .ToArray());

1
আমি এই পদ্ধতিটি পছন্দ করি: আপনি কেবল স্ট্রিংয়ের মধ্যে অনুমোদিত অক্ষর রাখেন (যা একটি চর অ্যারে ছাড়া আর কিছুই নয়)।
ডুড পাস্কেলু

6
আমি জানি এটি একটি পুরানো প্রশ্ন, তবে এটি একটি দুর্দান্ত উত্তর। যাইহোক, আমি যুক্ত করতে চেয়েছিলাম যে সি # তে আপনি চর [] থেকে স্ট্রিংয়ে স্পষ্টভাবে বা স্পষ্টতই বলতে পারবেন না (পাগল, আমি জানি) সুতরাং আপনাকে এটি স্ট্রিং কনস্ট্রাক্টরে ফেলে দিতে হবে।
JNYRanger

1
আমি এটি নিশ্চিত করে নি, তবে আমি আশা করি পাথ.গেটআইনুডিয়্যালপ্যাথচারস () গেটইনুডিয়ালিফিলনেমচার্স () এর সুপারস্টেট এবং ফাইলের নাম এবং পাথ উভয়ই কভার করার জন্য, সুতরাং আমি সম্ভবত এটির পরিবর্তে এটি ব্যবহার করব।
এঙ্গুলারসেন

3
@ জাঞ্জ্রেয়াস আসলে পাথ.গেটইনুয়ালিডপ্যাথচারস () পথের একটি উপসেট বলে মনে হচ্ছে etGetInuthorFileNameChars (), অন্যভাবে নয়। উদাহরণস্বরূপ, পাথ.গেটইনডিয়ালিপ্যাথচারস () ফিরে আসবে না? '
রাফায়েল কস্তা

1
এটি একটি ভাল উত্তর। আমি ফাইলের নাম তালিকা এবং ফাইলপথ তালিকা উভয়ই ব্যবহার করি: ____________________________ স্ট্রিং ক্লিনডেটা = নতুন স্ট্রিং (ডেটা.ওয়ে (x =>! পাথ.গেটইনডিয়ালিফিলনেমচার্স) () রয়েছে x (এক্স) && পাথ .GetInuthorPathChars () রয়েছে (x))। ToArray ());
goamn

27

এগুলি সমস্ত দুর্দান্ত সমাধান, তবে তারা সকলেই নির্ভর করে Path.GetInvalidFileNameChars, যা আপনার ধারণা হিসাবে বিশ্বাসযোগ্য হতে পারে না। এমএসডিএন ডকুমেন্টেশনে নিম্নলিখিত মন্তব্যটি লক্ষ্য করুন Path.GetInvalidFileNameChars:

এই পদ্ধতি থেকে ফিরে আসা অ্যারেটিতে ফাইল এবং ডিরেক্টরিগুলির নামগুলিতে অবৈধ অক্ষরের সম্পূর্ণ সেট থাকা গ্যারান্টিযুক্ত নয়। অবৈধ অক্ষরের সম্পূর্ণ সেট ফাইল সিস্টেমের দ্বারা পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, উইন্ডোজ-ভিত্তিক ডেস্কটপ প্ল্যাটফর্মে, অবৈধ পথের অক্ষরগুলিতে ASCII / ইউনিকোড অক্ষর 1 থেকে 31 এর মধ্যে, পাশাপাশি উদ্ধৃতি ("), (<) এর চেয়ে কম, পাইপ (|), ব্যাকস্পেস ( \ খ), নাল (\ 0) এবং ট্যাব (\ t)।

এটি Path.GetInvalidPathCharsপদ্ধতির সাথে আরও ভাল কিছু নয় । এটিতে ঠিক একই মন্তব্য রয়েছে।


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

1
আমি জানি এটি একটি পুরানো মন্তব্য তবে, @ জন আপনি অন্য ফাইল সিস্টেমে লিখতে চাইতে পারেন, সম্ভবত এই কারণেই এখানে একটি সতর্কতা রয়েছে।
fantastik78

3
@ ফান্টাসটিক 7878 টি ভাল বিষয়, তবে এই ক্ষেত্রে আমি আমার দূরবর্তী এফএস নির্দিষ্ট করতে একটি অতিরিক্ত এনাম যুক্তি রাখতে চাই। এটি যদি খুব বেশি রক্ষণাবেক্ষণের প্রচেষ্টা হয় (যা সম্ভবত এটি সম্ভব হয়) তবে এই পুরো পদ্ধতিটি এখনও একটি খারাপ ধারণা, কারণ এটি আপনাকে সুরক্ষার ভুল ধারণা দেয়।
জানুয়ারী

1
@ জান আমি আপনার সাথে পুরোপুরি একমত, আমি কেবল সতর্কবার্তাটি নিয়ে বিতর্ক করছি।
fantastik78

মজার বিষয় হল এটি এক ধরণের "ব্ল্যাকলিস্টিং" অবৈধ অক্ষর। এখানে কেবল পরিচিত বৈধ অক্ষরগুলি "শ্বেতলিস্ট" করা কি ভাল হবে না ?! অনুমতিপ্রাপ্ত অ্যাপ্লিকেশনগুলিকে হোয়াইটলিস্ট করার পরিবর্তে বোকা "ভাইরাস স্ক্যানার" ধারণাটি মনে করিয়ে দেয় ....
বার্নহার্ড

26

ফাইলের নামগুলির জন্য:

var cleanFileName = string.Join("", fileName.Split(Path.GetInvalidFileNameChars()));

পূর্ণ পথের জন্য:

var cleanPath = string.Join("", path.Split(Path.GetInvalidPathChars()));

মনে রাখবেন যে আপনি যদি এটি কোনও সুরক্ষা বৈশিষ্ট্য হিসাবে ব্যবহার করতে চান, তবে আরও শক্তিশালী পন্থাটি হবে সমস্ত পাথ প্রসারিত করা এবং তারপরে যাচাই করা উচিত যে ব্যবহারকারী সরবরাহিত পাথটি অবশ্যই কোনও ডিরেক্টরিতে ব্যবহারকারীর অ্যাক্সেস থাকা উচিত a


18

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

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


আমি বিশেষত দ্বিতীয় পরামর্শের সাথে একমত।
অরেগনহোস্ট

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

16

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

public string RemoveSpecialCharacters(string str)
{
    return Regex.Replace(str, "[^a-zA-Z0-9_]+", "_", RegexOptions.Compiled);
}

অথবা

<asp:RegularExpressionValidator ID="regxFolderName" 
                                runat="server" 
                                ErrorMessage="Enter folder name with  a-z A-Z0-9_" 
                                ControlToValidate="txtFolderName" 
                                Display="Dynamic" 
                                ValidationExpression="^[a-zA-Z0-9_]*$" 
                                ForeColor="Red">

5
আইএমএইচও এই সমাধানটি অন্যদের চেয়ে অনেক ভাল for সমস্ত অবৈধ অক্ষরের সন্ধানের পরিবর্তে কেবলমাত্র যা বৈধ তা সংজ্ঞায়িত করে।
আইগুরুশি

15

আমি এটি অর্জনের জন্য নিয়মিত ভাব প্রকাশ করি। প্রথমত, আমি গতিশীলভাবে রেজিक्स তৈরি করি।

string regex = string.Format(
                   "[{0}]",
                   Regex.Escape(new string(Path.GetInvalidFileNameChars())));
Regex removeInvalidChars = new Regex(regex, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant);

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


আজব, এটি আমার জন্য কাজ করে চলেছে। আমি সুযোগ পেলেই এটি ডাবল-চেক করব। আপনি কি আরও নির্দিষ্ট করে বলতে পারেন এবং ঠিক কী আপনার জন্য কাজ করছে না তা ব্যাখ্যা করতে পারেন?
জেফ ইয়েটস

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

@ জেফ: আপনি যদি সামান্য পরিবর্তন করেন তবে আপনার সংস্করণটি ম্যাথিউয়ের থেকে এখনও ভাল। কিভাবে আমার উত্তর দেখুন।
জানুয়ারী

2
আমি আরও কিছু অবৈধ ফাইল নামের ধরণ যুক্ত করব যা এমএসডিএন-এ পাওয়া যাবে এবং আপনার সমাধানটি নীচের new Regex(String.Format("^(CON|PRN|AUX|NUL|CLOCK\$|COM[1-9]|LPT[1-9])(?=\..|$)|(^(\.+|\s+)$)|((\.+|\s+)$)|([{0}])", Regex.Escape(new String(Path.GetInvalidFileNameChars()))), RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.CultureInvariant);
রেজিজেসে

13

আমি জেফ ইয়েটসের ধারণাটিকে একেবারে পছন্দ করি। আপনি যদি এটিকে কিছুটা সংশোধন করেন তবে এটি পুরোপুরি কাজ করবে:

string regex = String.Format("[{0}]", Regex.Escape(new string(Path.GetInvalidFileNameChars())));
Regex removeInvalidChars = new Regex(regex, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant);

উন্নতি হ'ল স্বয়ংক্রিয়ভাবে উত্পাদিত রেজেক্স থেকে রক্ষা পাওয়ার জন্য।


11

এখানে একটি কোড স্নিপেট রয়েছে যা .NET 3 এবং উচ্চতরদের জন্য সহায়তা করা উচিত।

using System.IO;
using System.Text.RegularExpressions;

public static class PathValidation
{
    private static string pathValidatorExpression = "^[^" + string.Join("", Array.ConvertAll(Path.GetInvalidPathChars(), x => Regex.Escape(x.ToString()))) + "]+$";
    private static Regex pathValidator = new Regex(pathValidatorExpression, RegexOptions.Compiled);

    private static string fileNameValidatorExpression = "^[^" + string.Join("", Array.ConvertAll(Path.GetInvalidFileNameChars(), x => Regex.Escape(x.ToString()))) + "]+$";
    private static Regex fileNameValidator = new Regex(fileNameValidatorExpression, RegexOptions.Compiled);

    private static string pathCleanerExpression = "[" + string.Join("", Array.ConvertAll(Path.GetInvalidPathChars(), x => Regex.Escape(x.ToString()))) + "]";
    private static Regex pathCleaner = new Regex(pathCleanerExpression, RegexOptions.Compiled);

    private static string fileNameCleanerExpression = "[" + string.Join("", Array.ConvertAll(Path.GetInvalidFileNameChars(), x => Regex.Escape(x.ToString()))) + "]";
    private static Regex fileNameCleaner = new Regex(fileNameCleanerExpression, RegexOptions.Compiled);

    public static bool ValidatePath(string path)
    {
        return pathValidator.IsMatch(path);
    }

    public static bool ValidateFileName(string fileName)
    {
        return fileNameValidator.IsMatch(fileName);
    }

    public static string CleanPath(string path)
    {
        return pathCleaner.Replace(path, "");
    }

    public static string CleanFileName(string fileName)
    {
        return fileNameCleaner.Replace(fileName, "");
    }
}

8

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

wvd_vegt


+1: খুব সত্য। আজ, নেট নেট in.০ এ কাজ করছেন, শীর্ষস্থানীয় উত্তর থেকে রেগেক্স সমাধান সমস্ত ব্যাকস্ল্যাশগুলিকে পুরো পথে ফেলেছে। তাই আমি দির পাথের জন্য একটি রেইজেক্স তৈরি করেছি এবং কেবল ফাইল নামের জন্য একটি
রেইজেক্স তৈরি করেছি

এটি সত্য হতে পারে তবে এটি প্রশ্নের উত্তর দেয় না। আমি নিশ্চিত নই যে এখানে ইতিমধ্যে থাকা কয়েকটি সম্পূর্ণ সমাধানের তুলনায় একটি অস্পষ্ট 'আমি এটি এটি করতাম' মারাত্মকভাবে সহায়ক (উদাহরণস্বরূপ নীচে লিলির উত্তর দেখুন)
ইয়ান গ্রেনার

6

আপনি যদি একক অক্ষরটিকে অবৈধ অক্ষরগুলি সরিয়ে বা প্রতিস্থাপন করেন তবে আপনার সংঘর্ষ হতে পারে:

<abc -> abc
>abc -> abc

এটি এড়াতে এখানে একটি সহজ পদ্ধতি:

public static string ReplaceInvalidFileNameChars(string s)
{
    char[] invalidFileNameChars = System.IO.Path.GetInvalidFileNameChars();
    foreach (char c in invalidFileNameChars)
        s = s.Replace(c.ToString(), "[" + Array.IndexOf(invalidFileNameChars, c) + "]");
    return s;
}

ফলাফল:

 <abc -> [1]abc
 >abc -> [2]abc

5

একটি ব্যতিক্রম নিক্ষেপ।

if ( fileName.IndexOfAny(Path.GetInvalidFileNameChars()) > -1 )
            {
                throw new ArgumentException();
            }

4

আমি এই দানবটি মজাদার জন্য লিখেছি, এটি আপনাকে রাউন্ডট্রিপ করতে দেয়:

public static class FileUtility
{
    private const char PrefixChar = '%';
    private static readonly int MaxLength;
    private static readonly Dictionary<char,char[]> Illegals;
    static FileUtility()
    {
        List<char> illegal = new List<char> { PrefixChar };
        illegal.AddRange(Path.GetInvalidFileNameChars());
        MaxLength = illegal.Select(x => ((int)x).ToString().Length).Max();
        Illegals = illegal.ToDictionary(x => x, x => ((int)x).ToString("D" + MaxLength).ToCharArray());
    }

    public static string FilenameEncode(string s)
    {
        var builder = new StringBuilder();
        char[] replacement;
        using (var reader = new StringReader(s))
        {
            while (true)
            {
                int read = reader.Read();
                if (read == -1)
                    break;
                char c = (char)read;
                if(Illegals.TryGetValue(c,out replacement))
                {
                    builder.Append(PrefixChar);
                    builder.Append(replacement);
                }
                else
                {
                    builder.Append(c);
                }
            }
        }
        return builder.ToString();
    }

    public static string FilenameDecode(string s)
    {
        var builder = new StringBuilder();
        char[] buffer = new char[MaxLength];
        using (var reader = new StringReader(s))
        {
            while (true)
            {
                int read = reader.Read();
                if (read == -1)
                    break;
                char c = (char)read;
                if (c == PrefixChar)
                {
                    reader.Read(buffer, 0, MaxLength);
                    var encoded =(char) ParseCharArray(buffer);
                    builder.Append(encoded);
                }
                else
                {
                    builder.Append(c);
                }
            }
        }
        return builder.ToString();
    }

    public static int ParseCharArray(char[] buffer)
    {
        int result = 0;
        foreach (char t in buffer)
        {
            int digit = t - '0';
            if ((digit < 0) || (digit > 9))
            {
                throw new ArgumentException("Input string was not in the correct format");
            }
            result *= 10;
            result += digit;
        }
        return result;
    }
}

1
আমি এটি পছন্দ করি কারণ এটি একই ফলস্বরূপ পাথ তৈরি করতে দুটি পৃথক স্ট্রিং থাকা এড়ানো হয়।
কিম

3

আমি মনে করি যে সমস্ত খারাপ চরিত্রের জন্য যাচাই করার চেষ্টা না করে একটি রেইজেক্স ব্যবহার করে এবং কোন অক্ষর অনুমোদিত কিনা তা নির্দিষ্ট করে দেওয়া যাচাই করা আরও সহজ। এই লিঙ্কগুলি দেখুন: http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx http://www.windowsdevcenter.com/pub/a/oreilly/windows/news/csharp_0101.html

এছাড়াও, "নিয়মিত অভিব্যক্তি সম্পাদক" এর জন্য অনুসন্ধান করুন, তারা প্রচুর সহায়তা করে। এমন কিছু কিছু রয়েছে যা আপনার জন্য সি # তে কোড আউটপুট দেয়।


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

যদিও অনলাইন রেজেক্স সম্পাদক / পরীক্ষকদের বিষয়ে আপনার পরামর্শের সাথে আমি সম্মত। আমি এগুলিকে অমূল্য বলে মনে করি (যেহেতু রেজেক্সেসগুলি কৌতুকময় জিনিস এবং সূক্ষ্মতায় পূর্ণ যা আপনাকে সহজেই ট্রিপ করতে পারে, আপনাকে এমন একটি রেজেক্স প্রদান করে যা প্রান্তের ক্ষেত্রে কিছু বুনো অপ্রত্যাশিত আচরণ করে)। আমার প্রিয়টি হচ্ছে regex101.com ( আমার পছন্দ হয় এটি কীভাবে রেজেক্সকে ভেঙে দেয় এবং কী মিলবে বলে প্রত্যাশা করে তা আপনাকে পরিষ্কারভাবে দেখায়)। আমি ডিবাগেক্স ডট কমকেও বেশ পছন্দ করি কারণ এটি ম্যাচ গ্রুপ এবং চরিত্রের শ্রেণিগুলির একটি কমপ্যাক্ট ভিজ্যুয়াল উপস্থাপনা পেয়েছে এবং কী নয়।
ড্যানিয়েল স্কট 0

3

এটি O (n) বলে মনে হচ্ছে এবং স্ট্রিংগুলিতে খুব বেশি মেমরি ব্যয় করে না:

    private static readonly HashSet<char> invalidFileNameChars = new HashSet<char>(Path.GetInvalidFileNameChars());

    public static string RemoveInvalidFileNameChars(string name)
    {
        if (!name.Any(c => invalidFileNameChars.Contains(c))) {
            return name;
        }

        return new string(name.Where(c => !invalidFileNameChars.Contains(c)).ToArray());
    }

1
আপনি 'যে কোনও' ফাংশনটি ব্যবহার করার সময় এটি ও (এন) মনে হয় না।
দ্বিতীয় তীর

@ আইয়ারোডাবস এবং এটি আপনার মতে কী?
অ্যালেক্সি এফ

আমি জানি না, আমি যখন আমার মন্তব্যটি লিখেছিলাম তখন এমনটা মনে হয় নি ... এখন যখন আমি এটি গণনা করার চেষ্টা করেছি, দেখে মনে হচ্ছে আপনি ঠিক আছেন।
দ্বিতীয় তীর

আপনার পারফরম্যান্স বিবেচনার কারণে আমি এটি নির্বাচন করেছি। ধন্যবাদ।
বেরেন্ড এঞ্জেলব্রেচট

3

এখানে উত্তরগুলি স্ক্যান করে, তারা সমস্ত ** অবৈধ ফাইল নামের অক্ষরের চর অ্যারে ব্যবহার করে জড়িত বলে মনে হচ্ছে।

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

অতীতে আমি খুব অবাক (হতবাক) হয়েছি ঠিক কত দ্রুত কোনও হ্যাশসেট (বা অভিধান) একটি তালিকার উপরে পুনরাবৃত্তি করে। স্ট্রিং সহ এটি একটি হাস্যকর কম সংখ্যা (স্মৃতি থেকে প্রায় 5-7 টি আইটেম)। বেশিরভাগ অন্যান্য সাধারণ ডেটা (অবজেক্ট রেফারেন্স, সংখ্যা ইত্যাদি) দিয়ে ম্যাজিক ক্রসওভারটি প্রায় 20 টি আইটেম হিসাবে মনে হয়।

পথটিতে 40 টি অবৈধ অক্ষর রয়েছে Iঅনুষ্ঠানিক ফাইলনামচার্স "তালিকা"। আজ একটি অনুসন্ধান করেছেন এবং স্ট্যাকওভারফ্লোতে এখানে বেশ ভাল একটি মানদণ্ড রয়েছে যা দেখায় যে হ্যাশসেটটি 40 টি আইটেমের জন্য অ্যারে / তালিকার অর্ধেক সময় নেবে: https://stackoverflow.com/a/10762995/949129

স্যানিটাইজিং পাথগুলির জন্য আমি যে সহায়ক শ্রেণি ব্যবহার করি তা এখানে। আমি এখন ভুলে গেছি কেন এতে আমার অভিনব প্রতিস্থাপন বিকল্প ছিল তবে এটি একটি বুদ্ধিমান বোনাস হিসাবে রয়েছে।

অতিরিক্ত বোনাস পদ্ধতি "ইসভিডলোক্যালপাথ "ও :)

(** যাঁরা নিয়মিত অভিব্যক্তি ব্যবহার করেন না)

public static class PathExtensions
{
    private static HashSet<char> _invalidFilenameChars;
    private static HashSet<char> InvalidFilenameChars
    {
        get { return _invalidFilenameChars ?? (_invalidFilenameChars = new HashSet<char>(Path.GetInvalidFileNameChars())); }
    }


    /// <summary>Replaces characters in <c>text</c> that are not allowed in file names with the 
    /// specified replacement character.</summary>
    /// <param name="text">Text to make into a valid filename. The same string is returned if 
    /// it is valid already.</param>
    /// <param name="replacement">Replacement character, or NULL to remove bad characters.</param>
    /// <param name="fancyReplacements">TRUE to replace quotes and slashes with the non-ASCII characters ” and ⁄.</param>
    /// <returns>A string that can be used as a filename. If the output string would otherwise be empty, "_" is returned.</returns>
    public static string ToValidFilename(this string text, char? replacement = '_', bool fancyReplacements = false)
    {
        StringBuilder sb = new StringBuilder(text.Length);
        HashSet<char> invalids = InvalidFilenameChars;
        bool changed = false;

        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            if (invalids.Contains(c))
            {
                changed = true;
                char repl = replacement ?? '\0';
                if (fancyReplacements)
                {
                    if (c == '"') repl = '”'; // U+201D right double quotation mark
                    else if (c == '\'') repl = '’'; // U+2019 right single quotation mark
                    else if (c == '/') repl = '⁄'; // U+2044 fraction slash
                }
                if (repl != '\0')
                    sb.Append(repl);
            }
            else
                sb.Append(c);
        }

        if (sb.Length == 0)
            return "_";

        return changed ? sb.ToString() : text;
    }


    /// <summary>
    /// Returns TRUE if the specified path is a valid, local filesystem path.
    /// </summary>
    /// <param name="pathString"></param>
    /// <returns></returns>
    public static bool IsValidLocalPath(this string pathString)
    {
        // From solution at https://stackoverflow.com/a/11636052/949129
        Uri pathUri;
        Boolean isValidUri = Uri.TryCreate(pathString, UriKind.Absolute, out pathUri);
        return isValidUri && pathUri != null && pathUri.IsLoopback;
    }
}

2
public static class StringExtensions
      {
        public static string RemoveUnnecessary(this string source)
        {
            string result = string.Empty;
            string regex = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
            Regex reg = new Regex(string.Format("[{0}]", Regex.Escape(regex)));
            result = reg.Replace(source, "");
            return result;
        }
    }

আপনি পরিষ্কারভাবে পদ্ধতি ব্যবহার করতে পারেন।


2

ফাইলের নাম থেকে অক্ষর থাকতে পারে না Path.GetInvalidPathChars(), +এবং #চিহ্ন, এবং অন্যান্য নির্দিষ্ট নাম থাকবে না। আমরা সমস্ত চেক এক শ্রেণিতে সংযুক্ত করেছি:

public static class FileNameExtensions
{
    private static readonly Lazy<string[]> InvalidFileNameChars =
        new Lazy<string[]>(() => Path.GetInvalidPathChars()
            .Union(Path.GetInvalidFileNameChars()
            .Union(new[] { '+', '#' })).Select(c => c.ToString(CultureInfo.InvariantCulture)).ToArray());


    private static readonly HashSet<string> ProhibitedNames = new HashSet<string>
    {
        @"aux",
        @"con",
        @"clock$",
        @"nul",
        @"prn",

        @"com1",
        @"com2",
        @"com3",
        @"com4",
        @"com5",
        @"com6",
        @"com7",
        @"com8",
        @"com9",

        @"lpt1",
        @"lpt2",
        @"lpt3",
        @"lpt4",
        @"lpt5",
        @"lpt6",
        @"lpt7",
        @"lpt8",
        @"lpt9"
    };

    public static bool IsValidFileName(string fileName)
    {
        return !string.IsNullOrWhiteSpace(fileName)
            && fileName.All(o => !IsInvalidFileNameChar(o))
            && !IsProhibitedName(fileName);
    }

    public static bool IsProhibitedName(string fileName)
    {
        return ProhibitedNames.Contains(fileName.ToLower(CultureInfo.InvariantCulture));
    }

    private static string ReplaceInvalidFileNameSymbols([CanBeNull] this string value, string replacementValue)
    {
        if (value == null)
        {
            return null;
        }

        return InvalidFileNameChars.Value.Aggregate(new StringBuilder(value),
            (sb, currentChar) => sb.Replace(currentChar, replacementValue)).ToString();
    }

    public static bool IsInvalidFileNameChar(char value)
    {
        return InvalidFileNameChars.Value.Contains(value.ToString(CultureInfo.InvariantCulture));
    }

    public static string GetValidFileName([NotNull] this string value)
    {
        return GetValidFileName(value, @"_");
    }

    public static string GetValidFileName([NotNull] this string value, string replacementValue)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException(@"value should be non empty", nameof(value));
        }

        if (IsProhibitedName(value))
        {
            return (string.IsNullOrWhiteSpace(replacementValue) ? @"_" : replacementValue) + value; 
        }

        return ReplaceInvalidFileNameSymbols(value, replacementValue);
    }

    public static string GetFileNameError(string fileName)
    {
        if (string.IsNullOrWhiteSpace(fileName))
        {
            return CommonResources.SelectReportNameError;
        }

        if (IsProhibitedName(fileName))
        {
            return CommonResources.FileNameIsProhibited;
        }

        var invalidChars = fileName.Where(IsInvalidFileNameChar).Distinct().ToArray();

        if(invalidChars.Length > 0)
        {
            return string.Format(CultureInfo.CurrentCulture,
                invalidChars.Length == 1 ? CommonResources.InvalidCharacter : CommonResources.InvalidCharacters,
                StringExtensions.JoinQuoted(@",", @"'", invalidChars.Select(c => c.ToString(CultureInfo.CurrentCulture))));
        }

        return string.Empty;
    }
}

পদ্ধতিতে GetValidFileNameসমস্ত ভুল ডেটা প্রতিস্থাপন করে _


2

উইন্ডোজ ফাইল নামকরণের জন্য যে কোনও অবৈধ অক্ষর থেকে স্ট্রিংয়ের জন্য একটি লাইনার:

public static string CleanIllegalName(string p_testName) => new Regex(string.Format("[{0}]", Regex.Escape(new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars())))).Replace(p_testName, "");

1
public static bool IsValidFilename(string testName)
{
    return !new Regex("[" + Regex.Escape(new String(System.IO.Path.GetInvalidFileNameChars())) + "]").IsMatch(testName);
}

0

এটি আপনাকে চাইবে এবং সংঘর্ষ এড়াতে চাইবে

 static string SanitiseFilename(string key)
    {
        var invalidChars = Path.GetInvalidFileNameChars();
        var sb = new StringBuilder();
        foreach (var c in key)
        {
            var invalidCharIndex = -1;
            for (var i = 0; i < invalidChars.Length; i++)
            {
                if (c == invalidChars[i])
                {
                    invalidCharIndex = i;
                }
            }
            if (invalidCharIndex > -1)
            {
                sb.Append("_").Append(invalidCharIndex);
                continue;
            }

            if (c == '_')
            {
                sb.Append("__");
                continue;
            }

            sb.Append(c);
        }
        return sb.ToString();

    }

0

আমি মনে করি যে প্রশ্নটি ইতিমধ্যে পূর্ণ নয়, উত্তরগুলি কেবল পরিষ্কার ফাইলের নাম বা পথ বর্ণনা করে ... উভয়ই নয়। এখানে আমার সমাধান:

private static string CleanPath(string path)
{
    string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
    Regex r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
    List<string> split = path.Split('\\').ToList();
    string returnValue = split.Aggregate(string.Empty, (current, s) => current + (r.Replace(s, "") + @"\"));
    returnValue = returnValue.TrimEnd('\\');
    return returnValue;
}

0

আমি একটি এক্সটেনশন পদ্ধতি তৈরি করেছি যা বেশ কয়েকটি পরামর্শকে একত্রিত করে:

  1. একটি হ্যাশ সেটে অবৈধ চরিত্রগুলি ধরে রাখা
  2. ASCII 127. নীচের অক্ষরগুলি ফিল্টার আউট Path.GetInvalidFileNameChars যেহেতু 0 থেকে 255 থেকে ASCII কোড সঙ্গে সম্ভব সব অবৈধ অক্ষর অন্তর্ভুক্ত নয় দেখুন এখানে এবং দুটিই MSDN
  3. প্রতিস্থাপনের চরিত্রটি নির্ধারণ করার সম্ভাবনা oss

সূত্র:

public static class FileNameCorrector
{
    private static HashSet<char> invalid = new HashSet<char>(Path.GetInvalidFileNameChars());

    public static string ToValidFileName(this string name, char replacement = '\0')
    {
        var builder = new StringBuilder();
        foreach (var cur in name)
        {
            if (cur > 31 && cur < 128 && !invalid.Contains(cur))
            {
                builder.Append(cur);
            }
            else if (replacement != '\0')
            {
                builder.Append(replacement);
            }
        }

        return builder.ToString();
    }
}

0

এখানে একটি ফাংশন যা কোনও ফাইলের নামের মধ্যে সমস্ত অবৈধ অক্ষরকে প্রতিস্থাপনের অক্ষর দ্বারা প্রতিস্থাপন করে:

public static string ReplaceIllegalFileChars(string FileNameWithoutPath, char ReplacementChar)
{
  const string IllegalFileChars = "*?/\\:<>|\"";
  StringBuilder sb = new StringBuilder(FileNameWithoutPath.Length);
  char c;

  for (int i = 0; i < FileNameWithoutPath.Length; i++)
  {
    c = FileNameWithoutPath[i];
    if (IllegalFileChars.IndexOf(c) >= 0)
    {
      c = ReplacementChar;
    }
    sb.Append(c);
  }
  return (sb.ToString());
}

উদাহরণস্বরূপ আন্ডারস্কোরটি প্রতিস্থাপনের অক্ষর হিসাবে ব্যবহার করা যেতে পারে:

NewFileName = ReplaceIllegalFileChars(FileName, '_');

আপনি যে উত্তর প্রদান করেছেন তা ছাড়াও দয়া করে কেন এবং কীভাবে এটি সমস্যার সমাধান করে তার সংক্ষিপ্ত বিবরণ দেওয়ার জন্য দয়া করে বিবেচনা করুন।
জেটেট

-7

বা আপনি ঠিক করতে পারেন

[YOUR STRING].Replace('\\', ' ').Replace('/', ' ').Replace('"', ' ').Replace('*', ' ').Replace(':', ' ').Replace('?', ' ').Replace('<', ' ').Replace('>', ' ').Replace('|', ' ').Trim();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.