2015-08-11 5 views
1

Я следующего рекурсивного поиска-функции:Поиск файлов с использованием регулярных выражений

public List<FileInfo> Search_Files(String strDir, String line) 
{ 
    List<FileInfo> files = new List<FileInfo>(); 

    try 
    { 
     foreach (String strFile in Directory.GetFiles(strDir,line+r)) 
     { 
      files.Add(new FileInfo(strFile)); 
     } 

     foreach (String strSubDir in Directory.GetDirectories(strDir)) 
     { 
      List<FileInfo> sublist = Search_Files(strSubDir, line); 

      foreach (FileInfo file_infow in sublist) 
      { 
       files.Add(file_infow); 
      } 
     } 
    } 
    catch (Exception) 
    { 
     ... 
    } 

    return (files); 
} 

значение переменной линейной выглядит как «1234». Теперь я хотел искать файлы, такие как: 1234c.something или 1234.something

Я создал следующие Regex:

Regex r = new Regex("[a-z].* | .*"); 

Я добавил его в линию строки, но он не работает. Почему это не работает и как я могу это исправить?

+2

Вы не можете передать регулярное выражение в '.GetDirectories'. Попробуйте '1234c. *' (Здесь '.' - буквальная точка, а '*' означает * любое количество символов *). Не забудьте изменить подпись на 'public List Search_Files (String strDir, String line, String r)' и если 'line'' '1234', то' r' должен быть 'c. *'. Работает ли это для вас? –

+0

Я не хочу только найти файлы c. *, Которые я хочу найти 1234 [a-z]. * Files. – lostluke

+0

Я вижу, я отправил ответ, надеюсь, что он сработает для вас. –

ответ

0

Если вы хотите совместить '.' вам нужно избежать этого как «\». '. *' сам по себе означает любой символ n-раз. Ознакомьтесь с особенностями форматов: https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx

Я также предлагаю вам использовать более строгое регулярное выражение. Если вы знаете, что имя вашего файла начинается с 1234, используйте его также в регулярном выражении.

0

В GetDirectories и GetFiles методов принимают searchPattern, который не регулярного выражения.

Строка поиска, соответствующая именам файлов в пути. Этот параметр может содержать комбинацию допустимых буквенных и групповых символов (* и ?) (см. Примечания), но не поддерживает регулярные выражения.

Вы можете отфильтровать результаты по следующим регулярным выражением:

var r = new Regex(@"\d{4}.*"); 
// var r = new Regex(@"^\d{4}.*"); // Use this if file names should start with the 4 digits. 
files.Add(Directory.GetFiles(strDir) 
      .Where(p => r.IsMatch(Path.GetFileName(p))) 
      .ToList()); 

\d{4}.* регулярное выражение соответствует 4 цифры (\d{4}) и любые 0 или больше символов, но символ новой строки.

+0

Я думаю, что вы не поняли мою ситуацию ... Имя файла не только 1234 ... Это может быть 123455, 99993, 324 ... , и теперь я хочу получить каждую версию этого идентификатора. Варианты, которые возможны для ПРИМЕРЫ для строки строки «1111», следующие два: 1111 [az] .anything и 1111.anything Вторая проблема не проблема: foreach (String strFile в Directory.GetFiles (strDir, line + ". *")) Но я не знаю, как найти первые. – lostluke

+0

Вы не можете конкатенировать строку и объект регулярного выражения, это то, что вы сделали. Что касается регулярного выражения, вы можете использовать '\ d +' вместо числа. Если вам нужно сопоставить только 4 числа, используйте '\ d {4}'. Если вы планируете разрешить два шаблона выше, шаблон по-прежнему идентичен: '\ d {4}. *', Потому что '[a-z]' является необязательным, не так ли? –

+0

Хорошо, я вижу. Но моя проблема в том, что у «id» есть переменные числа ... – lostluke

1

я использовал LINQ, дайте ему попробовать

string[] allFiles = Directory.GetFiles(@"C:\Users\UserName\Desktop\Files"); 
List<string> neededFiles = (from c in allFiles 
           where Path.GetFileName(c).StartsWith("fileStartName") 
           select c).ToList<string>(); 

foreach (var file in neededFiles) 
{ 
    // do the tesk you want with the matching files 
} 
+0

Я получил вашу мысль, «отредактировал» спасибо @stribizhev – manish

0

Есть два способа сделать это. Первый - использовать фильтр поиска Windows. Это то, что вы можете передать непосредственно методу GetFiles(). (EnumerateFiles() делает то же самое и может быть быстрее в этом случае, но это не имеет отношения к вашему вопросу).

Образец поиска в Windows использует * для представления «любого числа символов» и ? используется для представления одного неизвестного символа. Это не обычные выражения.

Вы можете выполнить поиск как это:

return Directory.EnumerateFiles(strDir, line + "*.*", SearchOption.AllDirectories) 
       .Select(f => new FileInfo(f)) 
       .ToList(); 

Второе это то, что вы изначально искали и который выполняет Linq запрос с фактическими регулярными выражениями. Это можно сделать так:

Regex pattern = new Regex(line + @".*\..*") 
// regex says use line, then anything any number of times, 
// and then a dot and then any chars any amount of times 

return Directory.EnumerateFiles(strDir, *.*, SearchOption.AllDirectories) 
       .Where(f => pattern.IsMatch(f)) 
       .Select(f => new FileInfo(f)) 
       .ToList(); 

Примечание: Приведенные два примера показывают, как также конвертировать предоставленные строки в FileInfo объекты как подписи вашего метода Search_Files требует в «Linq-пути."Кроме того, я использую SearchOption.AllDirectories флаг, который выполняет рекурсивный поиск для вас, без необходимости писать свой собственный

А почему ваш первоначально размещен метод не работает;. Есть две проблемы, связанные с ним

.
  1. вы пытаетесь объединить объект регулярного выражения со строкой. Это не возможно, потому что вы хотите Concat регулярного выражения шаблона строки. Это должно быть сделано до (или внутри) построения регулярного выражения как показано в моем примере.

  2. Предполагая, что вы не пытались конкретизировать объект регулярного выражения со строкой, шаблон Regex, который вы используете в значительной степени, всегда будет соответствовать чему-либо. Это ничего не ограничит.

+0

Спасибо, но я знал это решение раньше. Проблема в том, что есть такие файлы, как (если я ищу «1234»): 12344256754325.something Я не хочу получать эти файлы! С помощью своего метода я также получаю эти файлы ... – lostluke

+0

Можете ли вы более четко указать точный шаблон имен файлов? Использование моего второго варианта выше будет работать для вас, но вам нужно уточнить регулярное выражение, чтобы оно соответствовало лучше. – JNYRanger

Смежные вопросы