使用Regex从ListDirectoryDe​​tails中解析文件名

时间:2016-09-26 13:30:27

标签: c# regex ftp request ftpwebrequest

我正在尝试解析来自FileZilla FTP服务器的FTP ListDirectoryDetails响应。

主要问题是FileZilla服务器以不同的语言(文化)提供不同的输出。

我有两个来自FileZilla服务器的输出,两个都必须解析,这是我无法实现的。

格式如下所示:

drwxr-xr-x 1 ftp ftp              0 Sep 02 17:07 Can
-rw-r--r-- 1 ftp ftp              0 Jun 27 2016 Fan
drwxr-xr-x 1 ftp ftp              0 Sep 21 12:29 AA AA
-rw-r--r-- 1 ftp ftp             44 Sep 02 17:07 Debug.txt

我尝试使用正则表达式解决此问题,但在编译时失败。

我的正则表达式是:

(?<permissions>[drwx\-]+( (?<userandgroup>[A-Za-z]+ [A-Za-z]+) (?<size>\d+) (?<date>[A-Za-z]+ [\d:]+) (?<name> .*)

我需要更强大的正则表达式。也许只有文件名匹配正则表达式应该更好。

如何仅将文件名与正则表达式匹配?

3 个答案:

答案 0 :(得分:2)

要解析出一个文件名,只需获取第9个标记:

using (var ctx = new DbContext()) {

    var repo = new GenericRepository<Blog>(ctx);
    var repoTag = new GenericRepository<BlogTag>(ctx);
    var repoCategory = new GenericRepository<BlogCategory>(ctx);

    <the rest of your code where you build the `blog` object>

    ctx.SaveChanges();
}
^(?:[^ ]+ +){8}(.*)$

虽然对于这种简单的解析,您实际上可以按行将行拆分为令牌。你不需要正则表达式。

Regex regex = new Regex("^(?:[^ ]+ +){8}(.*)$");
Match match = regex.Match(line);
string filename = match.Groups[1].Value;

但是如果您只需要一个文件名,请不要首先使用string[] tokens = line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries); string filename = tokens[8]; 。使用ListDirectoryDetails。它只返回文件名。

如果需要解析文件属性,请使用支持FTP ListDirectory命令的FTP客户端。 MLSD不支持此功能。

答案 1 :(得分:1)

问题中的正则表达式是:正则表达式是:

(?<permissions>[drwx\-]+( (?<userandgroup>[A-Za-z]+ [A-Za-z]+) (?<size>\d+) (?<date>[A-Za-z]+ [\d:]+) (?<name> .*)

此表达式存在多个问题。

  • 第二个&#39;(&#39;应该是&#39;)&#39;。
  • 错过了链接计数。在前两个捕获组之间添加(\d+)(加一个空格)。
  • 仅允许userandgroupsize捕获之间允许一个空格。在+之前添加(?<size>\d+)
  • 月份的日期不匹配。将date捕获中的单个空格替换为[\d]+(两边必须有一个空格)。
  • name捕获前面有一个空格,并以空格作为其第一个字符/。删除其中一个。

合并这些改进提供了表达式:

(?<permissions>[drwx\-]+) (\d+) (?<userandgroup>[A-Za-z]+ [A-Za-z]+) +(?<size>\d+) (?<date>[A-Za-z]+ [\d]+ [\d:]+) (?<name>.*)

答案 2 :(得分:0)

我正在使用此正则表达式:

^([\-ld])([\-rwxs]{9})\s+(\d+)\s+(\w+)\s+(\w+)\s+(\d+)\s+(\w{3}\s+\d{1,2}\s+(?:\d{1,2}:\d{1,2}|\d{4}))\s+(.+)$

i在DART(在regex开头添加 r )和JS上都进行了测试,并且效果很好。 结果如下: https://regex101.com/r/8osTeQ/1

enter image description here

您可以这样迭代:

//code in dart
String s = "drw-rw----  2 owner group 7  May 12 11:30 index.html";

Iterable<Match> matches = regExp.allMatches(s);
for (Match match in matches) {
  print("${match.group(1)}\n");//type file or dir
  print("${match.group(2)}\n");//permission
  print("${match.group(3)}\n");//nb files
  print("${match.group(4)}\n");//owner
  print("${match.group(5)}\n");//group
  print("${match.group(6)}\n");//size
  print("${match.group(7)}\n");//date
  print("${match.group(8)}\n");//file/dir name
}