응용 프로그램에 배치 파일 이름 바꾸기 기능을 포함하고 싶습니다. 사용자는 대상 파일 이름 패턴을 입력 할 수 있으며 (패턴에서 일부 와일드 카드를 바꾼 후) Windows에서 올바른 파일 이름인지 확인해야합니다. 나는 정규 표현식을 사용하려고 노력했다.[a-zA-Z0-9_]+
다양한 언어 (예 : 움라우트 등)의 국가 별 문자가 많이 포함되어 있지 않습니다. 그러한 점검을 수행하는 가장 좋은 방법은 무엇입니까?
답변
Path.GetInvalidPathChars
및 에서 잘못된 문자 목록을 얻을 수 있습니다 GetInvalidFileNameChars
.
UPD : 정규 표현식에서이를 사용하는 방법에 대한 Steve Cooper의 제안 을 참조하십시오 .
UPD2 : MSDN의 비고 섹션에 따르면 “이 메서드에서 반환 된 배열에 파일 및 디렉터리 이름에 유효하지 않은 전체 문자 집합이 포함되어 있지는 않습니다.” sixlettervaliables 가 제공하는 답변 은 더 자세히 설명되어 있습니다.
답변
에서 MSDN의 “이름 지정 파일 또는 디렉터리,” 여기 합법적 인 파일 이름은 Windows에서 무엇을위한 일반적인 규칙입니다 :
다음을 제외하고 현재 코드 페이지 (유니 코드 / ANSI 127 이상)에 문자를 사용할 수 있습니다.
<
>
:
"
/
\
|
?
*
- 정수 표현이 0-31 인 문자 (ASCII 공간 미만)
- 대상 파일 시스템이 허용하지 않는 다른 문자 (예 : 마침표 또는 공백)
- DOS 이름 : CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 (및 AUX.txt 등을 피하십시오)
- 파일 이름은 모두 마침표입니다
몇 가지 선택 사항을 확인하십시오.
- 파일 경로 (파일 이름 포함)는 260자를 초과 할 수 없습니다 (
\?\
접두사를 사용하지 않음 ) - 사용시 32,000자를 초과하는 유니 코드 파일 경로 (파일 이름 포함)
\?\
(접두사가 디렉토리 구성 요소를 확장하여 32,000 한계를 초과 할 수 있음)
답변
들어 닷넷 프레임 워크 이전 3.5 이 작동합니다 :
정규식 일치는 당신에게 어떤 길을 가져다 줄 것입니다. 다음은 System.IO.Path.InvalidPathChars
상수를 사용하는 스 니펫입니다 .
bool IsValidFilename(string testName)
{
Regex containsABadCharacter = new Regex("["
+ Regex.Escape(System.IO.Path.InvalidPathChars) + "]");
if (containsABadCharacter.IsMatch(testName)) { return false; };
// other checks for UNC, drive-path format, etc
return true;
}
들어 닷넷 프레임 워크 3.0 이후 이 작동합니다 :
http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars(v=vs.90).aspx
정규식 일치는 당신에게 어떤 길을 가져다 줄 것입니다. 다음은 System.IO.Path.GetInvalidPathChars()
상수를 사용하는 스 니펫입니다 .
bool IsValidFilename(string testName)
{
Regex containsABadCharacter = new Regex("["
+ Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]");
if (containsABadCharacter.IsMatch(testName)) { return false; };
// other checks for UNC, drive-path format, etc
return true;
}
당신이 알고 나면, 당신은 또한 다른 형식, 예를 들어 확인해야 c:\my\drive
하고\\server\share\dir\file.ext
답변
그것을 사용하고 오류를 잡으십시오. 허용되는 집합은 파일 시스템이나 다른 버전의 Windows에서 변경 될 수 있습니다. 다시 말해, Windows가 이름을 좋아하는지 알고 싶다면 이름을 알려주고 알려주십시오.
답변
이 클래스는 파일 이름과 경로를 정리합니다. 처럼 사용
var myCleanPath = PathSanitizer.SanitizeFilename(myBadPath, ' ');
코드는 다음과 같습니다.
/// <summary>
/// Cleans paths of invalid characters.
/// </summary>
public static class PathSanitizer
{
/// <summary>
/// The set of invalid filename characters, kept sorted for fast binary search
/// </summary>
private readonly static char[] invalidFilenameChars;
/// <summary>
/// The set of invalid path characters, kept sorted for fast binary search
/// </summary>
private readonly static char[] invalidPathChars;
static PathSanitizer()
{
// set up the two arrays -- sorted once for speed.
invalidFilenameChars = System.IO.Path.GetInvalidFileNameChars();
invalidPathChars = System.IO.Path.GetInvalidPathChars();
Array.Sort(invalidFilenameChars);
Array.Sort(invalidPathChars);
}
/// <summary>
/// Cleans a filename of invalid characters
/// </summary>
/// <param name="input">the string to clean</param>
/// <param name="errorChar">the character which replaces bad characters</param>
/// <returns></returns>
public static string SanitizeFilename(string input, char errorChar)
{
return Sanitize(input, invalidFilenameChars, errorChar);
}
/// <summary>
/// Cleans a path of invalid characters
/// </summary>
/// <param name="input">the string to clean</param>
/// <param name="errorChar">the character which replaces bad characters</param>
/// <returns></returns>
public static string SanitizePath(string input, char errorChar)
{
return Sanitize(input, invalidPathChars, errorChar);
}
/// <summary>
/// Cleans a string of invalid characters.
/// </summary>
/// <param name="input"></param>
/// <param name="invalidChars"></param>
/// <param name="errorChar"></param>
/// <returns></returns>
private static string Sanitize(string input, char[] invalidChars, char errorChar)
{
// null always sanitizes to null
if (input == null) { return null; }
StringBuilder result = new StringBuilder();
foreach (var characterToTest in input)
{
// we binary search for the character in the invalid set. This should be lightning fast.
if (Array.BinarySearch(invalidChars, characterToTest) >= 0)
{
// we found the character in the array of
result.Append(errorChar);
}
else
{
// the character was not found in invalid, so it is valid.
result.Append(characterToTest);
}
}
// we're done.
return result.ToString();
}
}
답변
이것이 내가 사용하는 것입니다 :
public static bool IsValidFileName(this string expression, bool platformIndependent)
{
string sPattern = @"^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)[^\x00-\x1f\\?*:\"";|/]+$";
if (platformIndependent)
{
sPattern = @"^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?))\\)*[^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?$";
}
return (Regex.IsMatch(expression, sPattern, RegexOptions.CultureInvariant));
}
첫 번째 패턴은 Windows 플랫폼에 대해서만 유효하지 않은 / 잘못된 파일 이름 및 문자를 포함하는 정규식을 작성합니다. 두 번째는 동일하지만 이름이 모든 플랫폼에 합법적임을 보장합니다.
답변
한 가지 코너 케이스를 염두에두면 처음 알게되었을 때 놀랐습니다. Windows는 파일 이름에 공백 문자를 허용합니다! 예를 들어 다음은 Windows에서 합법적이고 고유 한 파일 이름 (따옴표 제외)입니다.
"file.txt"
" file.txt"
" file.txt"
이것에서 한 가지 탈취 : 파일 이름 문자열에서 선행 / 후행 공백을 자르는 코드를 작성할 때주의하십시오.