2014-04-08 2 views
1

저는 C# 및 Visual Studio 2010을 사용하고 있습니다. 문자열 (이 경우 경로)과 일치 시키려고 노력하고 있습니다. 알아낼 수있는 패턴을 만듭니다. 그것은 유효한 패턴이거나 그렇지 않습니다. 아래 예제는 임의로 구성되어 있지만 포함되어 있습니다.패턴 일치 경로 + 파일 (UNC?)

그래서 문자열로 들어오는 UNC 경로와 일치하는 패턴을 만들려고합니다. 예 :

"\\\\Apple-butter27\\AliceFakePlace\\SomeDay\\Grand100\\Some File Name Stuff\\Yes these are fake words\\One more for fun2000343\\myText.txt" 

위는 패턴 일치를 시도하는 파일 경로의 예입니다. 나는이 패턴과 일치하려고 해요 : 내가 수익을 창출하고

@"\\\\[a-zA-Z0-9-]+\\\w+\\\w+\\\w+\\((\w+)*(\s+)*)*\\((\w+)*(\s+)*)*\\((\w+)*(\s+)*)*\\w+\.txt"; 

것은 내가 내 파일 (들)에 도달 할 때까지 7 개 폴더가있을 것입니다. 나는 거의 모든 세그먼트에 대해 공백, 문자 및 숫자의 콤보를 찾아야 할 것입니다.

나는 그런 내 패턴이 시도 테스트의 나의 첫 번째 반복으로 작은 비트를 일치시켜 시작해보십시오 않았다 : 내가 추가하는 경우

@"\\\\"; 

그리고 처음 몇 문자와 일치하는 것이기 때문에이 작동하지만, 이것에 :

@"\\\\[a-zA-Z0-9-]+"; 

실패합니다. 그래서 문자열이 그것을 두배로 늘려서 "\"를 두배로 늘려서 8 "\"혼자서 다시 시도해 보았지만 어쩌면 그렇게 생각했습니다.하지만 실패했습니다.

이전 패턴 내 목표는 내가 구글에 모든 웹 사이트를 통해 찾고 있었어요 "\\\\ 애플 butter27"

일치하는 것입니다,하지만 난 볼 수있는 패턴 중 어느 것도 UNC 물건 일치하지 않습니다 확실히 내 문제입니다.

누군가가 내가이 패턴을 잘못 이해하고 있다고 말할 수 있다면 정말 고맙겠습니다. 길다는 것을 알기 때문에 최소한 출발점이 될 것입니다. 아마도 정말로 복잡한 것일 것입니다 ...하지만 누군가가 일반적인 잘못을 지적 할 수 있다면.

\\Apple-butter27\AliceFakePlace\SomeDay\Grand100\Some File Name Stuff\Yes these are fake words\One more for fun2000343\myText.txt 

나는 누군가가 불을 수 있습니다 그래서 만약 정말 나를 혼동하기 시작 그래서 UNC 경로와 일치하는 패턴을 시도하는 새로운 해요 : 그것은 문자열이 아닌 상태에서 경로이기 때문에

비록 그것은 다음과 같습니다 방법, 나는 그것을 많이 감사 할 것이다.

나는 을 사용하고 있습니다. Regex의 기능을 사용하여 패턴이 일치하는지 확인하고 일치가 성공 또는 실패한 경우 단순히 메시지를 인쇄합니다. 솔루션의 문자열이 아닌 다른 경로로 작업하는 것이 좋은 통찰력이 아니라면 필자의 주된 관심사는 패턴이다.당신이 경로가 존재하는지 확인하려는 경우

+0

Regex가 모든 문제에 가장 적합한 도구라고 항상 가정하지 않는 것이 좋습니다! 귀하의 가정으로 인해, 이것은 [XY 문제] (http://meta.stackexchange.com/a/66378)입니다. –

+0

Regex이 내 해결책이라고 생각합니다. 나는 그것이 특정 파일 경로를 내려가는 것을 멈추고 원하는 정보를 찾기 위해 다른 사람들을 향해 나아 가기를 원한다면 경로가 특정 방법의 원인인지 확인하고 싶다. – user3003304

답변

6

없음 정규식, 또는

필요하지하여 System.Uri 클래스의 구문 분석에 내장 된 사용

foreach (var path in new [] { @"C:\foo\bar\", @"\\server\bar" }) 
{ 
    var uri = new Uri(path); 

    if (uri.IsUnc) 
    { 
     Console.WriteLine("Connects to host '{0}'", uri.Host); 
    } 
    else 
    { 
     Console.WriteLine("Local path"); 
    } 
} 

인쇄 :

로컬 경로
은 '서버'를 호스트에 연결

그리고 당신은 바퀴를 다시 발명하지 않는 확장에 대해 일치 시키려면, Path.GetExtension를 사용

var path = "\\some\really long and complicated path\foo.txt"; 
var extensionOfPath = Path.GetExtension(path); 

if (string.Equals(".txt", extensionOfPath, StringComparison.CurrentCultureIgnoreCase)) 
{ 
    Console.WriteLine("It's a txt"); 
} 
else 
{ 
    Console.WriteLine("It's a '{0}', which is not a txt", extensionOfPath); 
} 

는 일반적으로, 당신이 문제를 해결 할 때 정규식에 점프 피하기 추천하려합니다. 다른 사람이 문제를 해결했는지 스스로 자문 해보십시오 (example for HTML). regex가 CodingHorror에 나쁜 담당자가있는 이유와 (덜 심각하게) on xkcd에 대한 좋은 토론이 있습니다. 내가이 일에 가장 적합한 도구가 아닙니다 유지 정규식을 사용하여 구부러진 경우

정규식 버전

, 그것은 수행 할 수 있습니다. 공백과 주석을 사용하면 코드를 읽을 수 있습니다.

string input = @"\\Apple-butter27\AliceFakePlace\SomeDay\Grand100\Some File Name Stuff\Yes these are fake words\One more for fun2000343\myText.txt"; 
Regex regex = new Regex(@" 
    ^
    (?: 
     # if server is present, capture to a named group 
     # use a noncapturing group to remove the surrounding slashes 
     # * is a greedy match, so it will butt up against the following directory search 
     # this group may or may not occur, so we allow either this or the drive to match (|) 
     (?:\\\\(?<server>[^\\]*)\\) 
     # if there is no server, then we best have a drive letter 
     |(?:(?<drive>[A-Z]):\\) 
    ) 
    # then we have a repeating group (+) to capture all the directory components 
    (?: 
     # each directory is composed of a name (which does not contain \\) 
     # followed by \\ 
     (?<directory>[^\\]*)\\ 
    )+ 
    # then we have a file name, which is identifiable as we already ate the rest of 
    # the string. So, it is just all non-\\ characters at the end. 
    (?<file>[^\\]*) 
    $", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); 

var matches = regex.Match(input).Groups; 

foreach (var group in regex.GetGroupNames()) 
{ 
    Console.WriteLine("Matched {0}:", group); 
    foreach (var value in matches[group].Captures.Cast<Capture>()) 
    { 
     Console.WriteLine("\t{0}", value.Value); 
    } 
} 

인쇄

Matched server: 
     Apple-butter27 
Matched drive: 
Matched directory: 
     AliceFakePlace 
     SomeDay 
     Grand100 
     Some File Name Stuff 
     Yes these are fake words 
     One more for fun2000343 
Matched file: 
     myText.txt 

지금 막 같은데요 ...

당신이 집의 디렉토리를 호출하고 다층 구조를 구축 응용 프로그램의 일종을 가지고있는 것처럼 그것은 소리

아래에. 다음과 같은 것 :

그리고 실제 파일을 찾고 있는지, 알 수 없는지를 묻습니다. 어느 쪽이든, 우리는 C:\root directory\에 대해 알고 있으며 실제 파일이 있다고 생각합니다. 우리는 다음 디렉토리 트리를 가지고 실제 파일을 찾을 열거 할 수 있습니다 :

var diRoot = new DirectoryInfo(@"C:\drop"); 

var projectDirectories = FindProjects(diRoot); 

// get all of the files in all of the project directories of type .txt 
var projectFiles = projectDirectories.SelectMany(di => di.GetFiles("*.txt")); 

// projectFiles now contains: 
// actual.txt 
// files.txt 

private static IEnumerable<DirectoryInfo> FindProjects(DirectoryInfo cDir, int depth = 0) 
{ 
    foreach (var di in cDir.GetDirectories()) 
    { 
     // assume projects are three levels deep 
     if (depth == 3) 
     { 
      // it's a project, so we can return it 
      yield return di; 
     } 
     else 
     { 
      // pass it through, return the results 
      foreach (var d in FindProjects(di, depth + 1)) 
       yield return d; 
     } 
    } 
} 

을 우리가 경로의 문자열 조작을하고 있지 않기 때문에, 우리는 투명하게 로컬 및 UNC 경로를 처리 할 수 ​​있습니다.

+0

폴더가 있는지 여부는 신경 쓰지 않습니다. 이미 검사가 있습니다. 나는 많은 폴더 다이빙을하고 있으며, 쉽게 할 수 있지만, "이런 식으로하지 않으면 다음과 같은 말을함으로써 몇 가지 경로를 차단하여 시간을 줄이기 위해 노력하고 싶다. 그것으로보기 ". 따라서 폴더에 대한 명명 규칙이 있지만 궁극적으로는 잠깐 동안의 폴더 다이빙을 차단하려고합니다. Regex가 해결책이라고 믿는 이유는 그렇지 않다면 "이게 맘에 안 든다면 이렇게하지 마라"와 같은 일을 어떻게해야할지 모르겠기 때문이다. – user3003304

+0

나는 당신이하려는 것을 이해하지 못한다. 'Uri'도'Path'도 디스크 상에 파일이 있는지 요구하거나 검사하지 않으며, 정규 표현도하지 않습니다. Regex는 일반 문자열 (예 : tmp314 ->'tmp \ d {3}')과 일치 할 때 유용합니다. 사용자가 생성 한 경로는 모두 있지만 ~ 정규입니다. – Mitch

+0

필자는 http://msdn.microsoft.com/en-us/library/bb513869.aspx를 기반으로 파일을 처리하는 코드를 가지고 있습니다. 내가 정규식을 사용하는 이유를 확인하는 데 필요한 몇 가지 물건이 경로에 있습니다. 나는 그것을 사용하여 "나는 이런 식으로하지 마라"라는 말을 사용하기를 희망하는 파일을 찾는 것에 대해 아무 것도하지 않습니다. 그것이 정규 표현식의 목표입니다. – user3003304

1

, 당신은 같은 것을 할 수 있습니다

FileInfo fi = new FileInfo(@""\\\\Apple-butter27\\AliceFakePlace\\SomeDay\\Grand100\\Some File Name Stuff\\Yes these are fake words\\One more for fun2000343\\myText.txt""); 
bool exists = fi.Exists; 

을하지만 유효성 검사를 실행하는 시점에서 이러한 경로에 액세스 할 수없는 경우 \\ 애플 butter27 찾기 위해이 패턴을 사용할 수 있습니다

const string rootPattern = @"(\\\\[a-zA-Z-_0-9]+)"; 

const RegexOptions regexOptions = RegexOptions.Compiled; 

var regex = new Regex(rootPattern, regexOptions); 

      foreach (Match match in regex.Matches(fileName)) 
      { 
       if (match.Success && match.Groups.Count >= 1) 
       { 
        shareRoot = match.Groups[0].Value; 
       } 
      } 

나는이 패턴을 시도하고 그룹 0 정확히 저를 제공 \\ 애플 butter27 당신은 [괄호]의 다른 문자를 추가해야 할 것이다 당신은 수도 와 같은 만남은 '.'일 수 있습니다.

0

나는 System의 사용법에 동의 할 수 없지만.Uri (당신이 필요로하는 도구 일 것입니다); 나는 우리가 엄격 패턴 매칭 정규식을 준수 할 필요가 있다고 가정합니다 :

 const string tString = "\\\\Apple-butter27\\AliceFakePlace\\SomeDay\\Grand100\\Some File Name Stuff\\Yes these are fake words\\One more for fun2000343\\myText.txt"; 
     const string tRegexPattern = @"(\\\\)?((?<Folder>[a-zA-Z0-9- ]+)(\\))"; 
     const RegexOptions tRegexOptions = RegexOptions.Compiled; 

     Regex tRegex = new Regex(tRegexPattern, tRegexOptions); 

     Console.WriteLine(tString); 

     if (tRegex.Matches(tString).Count == 7) 
     { 
      foreach (Match iMatch in tRegex.Matches(tString)) 
      { 
       if (iMatch.Success && iMatch.Groups["Folder"].Length > 0) 
       { 
        Console.WriteLine(iMatch.Groups["Folder"].Value); 
       } 
      } 
     } 
     else 
      throw new Exception("String did not have a path of depth 7"); 

만 경기에 7 개 그룹을 정규식을 강제 할 수 있지만, 정규식은 정말 패턴 매칭이 아닌 '정신이 이상한 논리'를 위해 설계되었습니다.

? < 폴더 > 그룹은 구분 기호 (뒤에 '\')가 오는 경우에만 일치하므로 파일 또는 파일 확장자가 아닌 폴더 패턴에서만 일치합니다.

+0

파일 이름에 밑줄이있는 파일이나 마침표가있는 디렉토리 또는 실제로 이름에 허용되는 다른 수천 개의 문자가있는 파일 이름을 지정하면 오류가 발생합니다. 그러한 솔루션을 현지화 할 수 없다는 사실에 신경 쓰지 마십시오. – Mitch