2011-10-18 29 views
6

Tôi mới sử dụng cụm từ thông dụng. Tôi cần trích xuất đường dẫn từ các dòng sau:Regex để khớp với đường dẫn trong C#

XXXX  c:\mypath1\test 
YYYYYYY    c:\this is other path\longer 
ZZ  c:\mypath3\file.txt 

Tôi cần triển khai phương thức trả về đường dẫn của một dòng nhất định. Cột đầu tiên là một từ có từ 1 ký tự trở lên, không bao giờ trống, cột thứ hai là đường dẫn. Dấu phân cách có thể là 1 hoặc nhiều dấu cách hoặc một hoặc nhiều tab hoặc cả hai. (. Đây là giả định rằng cột đầu tiên không bao giờ chứa dấu cách hoặc tab)

+0

đầu vào là tệp hay dòng riêng? –

+0

@RoyiNamir có quan trọng không? – username

+0

có. việc điều trị cho đường dây và tập tin là khác nhau. trừ khi bạn đọc nó theo từng dòng từ tệp tex và sau đó bạn cũng cần phải chăm sóc các ký tự ngắt dòng, v.v. –

Trả lời

7

Nghe có vẻ với tôi như bạn chỉ muốn

string[] bits = line.Split(new char[] { '\t', ' ' }, 2, 
          StringSplitOptions.RemoveEmptyEntries); 
// TODO: Check that bits really has two entries 
string path = bits[1]; 

EDIT: Là một biểu thức chính quy bạn có thể có lẽ chỉ làm:

Regex regex = new Regex(@"^[^ \t]+[ \t]+(.*)$"); 

mẫu mã:

using System; 
using System.Text.RegularExpressions; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     string[] lines = 
     { 
      @"XXXX  c:\mypath1\test", 
      @"YYYYYYY    c:\this is other path\longer", 
      @"ZZ  c:\mypath3\file.txt" 
     }; 

     foreach (string line in lines) 
     { 
      Console.WriteLine(ExtractPathFromLine(line)); 
     } 
    } 

    static readonly Regex PathRegex = new Regex(@"^[^ \t]+[ \t]+(.*)$"); 

    static string ExtractPathFromLine(string line) 
    { 
     Match match = PathRegex.Match(line); 
     if (!match.Success) 
     { 
      throw new ArgumentException("Invalid line"); 
     } 
     return match.Groups[1].Value; 
    }  
} 
+0

Đường dẫn có thể có dấu cách, vì vậy đường dẫn thứ hai khá tệ. – xanatos

+0

@Jon: Xin lỗi, tôi cần một expresion thường xuyên kể từ khi tôi đang sử dụng .NET 1.1 và tôi không có quyền truy cập vào StringSplitOptions.RemoveEmptyEntries quá tải. Dù sao cũng cảm ơn bạn! –

+0

@ DanielPeñalba: Sẽ rất hữu ích khi nói như vậy để bắt đầu - yêu cầu .NET 1.1 là rất hiếm trong những ngày này. Sẽ chỉnh sửa. –

4
StringCollection resultList = new StringCollection(); 
try { 
    Regex regexObj = new Regex(@"(([a-z]:|\\\\[a-z0-9_.$]+\\[a-z0-9_.$]+)?(\\?(?:[^\\/:*?""<>|\r\n]+\\)+)[^\\/:*?""<>|\r\n]+)"); 
    Match matchResult = regexObj.Match(subjectString); 
    while (matchResult.Success) { 
     resultList.Add(matchResult.Groups[1].Value); 
     matchResult = matchResult.NextMatch(); 
    } 
} catch (ArgumentException ex) { 
    // Syntax error in the regular expression 
} 

Breakdown:

@" 
(       # Match the regular expression below and capture its match into backreference number 1 
    (       # Match the regular expression below and capture its match into backreference number 2 
     |        # Match either the regular expression below (attempting the next alternative only if this one fails) 
     [a-z]       # Match a single character in the range between “a” and “z” 
     :        # Match the character “:” literally 
     |        # Or match regular expression number 2 below (the entire group fails if this one fails to match) 
     \\       # Match the character “\” literally 
     \\       # Match the character “\” literally 
     [a-z0-9_.$]     # Match a single character present in the list below 
              # A character in the range between “a” and “z” 
              # A character in the range between “0” and “9” 
              # One of the characters “_.$” 
      +        # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
     \\       # Match the character “\” literally 
     [a-z0-9_.$]     # Match a single character present in the list below 
              # A character in the range between “a” and “z” 
              # A character in the range between “0” and “9” 
              # One of the characters “_.$” 
      +        # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
    )?       # Between zero and one times, as many times as possible, giving back as needed (greedy) 
    (       # Match the regular expression below and capture its match into backreference number 3 
     \\       # Match the character “\” literally 
     ?        # Between zero and one times, as many times as possible, giving back as needed (greedy) 
     (?:       # Match the regular expression below 
     [^\\/:*?""<>|\r\n]    # Match a single character NOT present in the list below 
              # A \ character 
              # One of the characters “/:*?""<>|” 
              # A carriage return character 
              # A line feed character 
      +        # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
     \\       # Match the character “\” literally 
    )+       # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
    ) 
    [^\\/:*?""<>|\r\n]    # Match a single character NOT present in the list below 
            # A \ character 
            # One of the characters “/:*?""<>|” 
            # A carriage return character 
            # A line feed character 
     +        # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
) 
" 
+1

Điều này có vẻ rất phức tạp về cơ bản có được mọi thứ sau tập hợp các dấu cách/tab đầu tiên. –

+0

@JonSkeet Tôi đồng ý. Đó là một regex tổng quát hơn cho đường dẫn cửa sổ. – FailedDev

+0

@FailedDev nó không hoạt động ví dụ cho "k: \ test \ test". Nếu tôi cố gắng vượt qua đường dẫn như ** \\ test \ t><* st ** thì nó sẽ hợp lệ. Tôi tìm thấy regex này '^ (?: [C-zC-Z] \: | \\) (\\ [a-zA-Z _ \ - \ s0-9 \.] +) +'. Nó xác nhận đường dẫn chính xác theo ý kiến ​​của tôi. Tìm thấy nó [ở đây] (https://www.codeproject.com/Tips/216238/Regular-Expression-to-Validate-File-Path-and-Exten) – Potato

0

Regex Tester là một Website tốt để kiểm tra Regex nhanh.

Regex.Matches(input, "([a-zA-Z]*:[\\[a-zA-Z0-9 .]*]*)"); 
Các vấn đề liên quan