How to remove illegal characters from path and filenames?

前端 未结 29 2986
离开以前
离开以前 2020-11-22 17:18

I need a robust and simple way to remove illegal path and file characters from a simple string. I\'ve used the below code but it doesn\'t seem to do anything, what am I miss

相关标签:
29条回答
  • 2020-11-22 17:42

    This seems to be O(n) and does not spend too much memory on strings:

        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());
        }
    
    0 讨论(0)
  • 2020-11-22 17:42
    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;
            }
        }
    

    You can use method clearly.

    0 讨论(0)
  • 2020-11-22 17:44

    File name can not contain characters from Path.GetInvalidPathChars(), + and # symbols, and other specific names. We combined all checks into one class:

    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;
        }
    }
    

    Method GetValidFileName replaces all incorrect data to _.

    0 讨论(0)
  • 2020-11-22 17:46

    Here's a code snippet that should help for .NET 3 and higher.

    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, "");
        }
    }
    
    0 讨论(0)
  • 2020-11-22 17:47

    One liner to cleanup string from any illegal chars for windows file naming:

    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, "");
    
    0 讨论(0)
提交回复
热议问题