【问题标题】:Regex splits one string, but not the other正则表达式拆分一个字符串,但不拆分另一个
【发布时间】:2014-05-15 09:44:21
【问题描述】:

我有一个用于从 Windows 服务器拆分 FTP 目录列表的正则表达式,它会在一种情况下拆分字符串,而不是另一种情况。我不是正则表达式专家,想知道是否有人可以告诉我为什么其中一个会被拆分,而另一个不会?

我希望它拆分字符串,所以我有以下组件:

 DateTime
 IsDirectory/IsFile  (<DIR> is present or not)
 Size
 FileName

(1) 不会拆分字符串,(2) 会拆分

//05-14-14  11:29AM                    0 New Text Document.txt (1)
//05-12-14  12:17PM       <DIR>          TONY (2)

string directorylisting = "05-14-14  11:29AM                    0 New Text Document.txt";
string regex = @"^(\d\d-\d\d-\d\d)\s+(\d\d:\d\d(AM|PM))\s+(<DIR>)?\s+(\d*)\s+([\w\._\-]+)\s*$";
var split = Regex.Split(directorylisting, regex);

【问题讨论】:

  • 那么,您拆分的确切标准是什么?如果您解释一下,将更容易找到正确的正则表达式:p
  • @Kilazur 我更新了我的问题

标签: c# regex split


【解决方案1】:

我不确定这里使用 split 方法是不是好方法,我建议你使用 match 方法和命名捕获但所有目录列表都作为输入字符串:

string pattern = @"(?mx)^
    (?<date> [0-9]{2}(?:-[0-9]{2}){2} ) [ \t]+
    (?<time> [0-9]{2}:[0-9]{2}[AP]M   ) [ \t]+ 
    (?:
        (?<isDir>    <DIR>  )
      |
        (?<filesize> [0-9]+ )
    ) [ \t]+
    (?(isDir)
        (?<dirname>  [^<>*|"":/\\?\u0001-\u001f\n\r]{1,32768}? )
      |
        (?<filename> [^<>*|"":/\\?\u0001-\u001f\n\r]{1,32768}? )
    ) [^\S\n]* $";

foreach (Match m in Regex.Matches(listing, pattern)) {
    // for each line you can test the group isDir to know if it is 
    // a directory or not
}

(注意:我尝试了解 Microsoft 的文件名/目录名规则,但我不是 100% 确定,请随时改进这些字符类)

如果你需要保证所有的行都是连续的(使用split方法时就是这种情况),你可以在模式的开头加上\G,在结尾加上\n?(在美元之后) .

最后一个字符类[^\S\n]* 可能替换为\r?(我无法测试,我不使用Windows)和[ \t] 替换为[ ]\t(我让你测试它) )。

【讨论】:

    【解决方案2】:

    问题似乎到了最后:\s*$

    正则表达式的早期部分,即

    ^(\d\d-\d\d-\d\d)\s+(\d\d:\d\d(AM|PM))\s+(<DIR>)?\s+(\d*)\s+([\w\._\-]+)
    

    将文件夹匹配到“new”和“TONY”

    demo

    但之后有文本,\s*$ 不会匹配该文本,因为它只允许空格到行尾。

    【讨论】:

    • 解决了这个问题,所以现在它拆分了字符串 (1),但是我将如何防止它将“New Text Document.txt”拆分为“New”和“Text Document.txt” ?
    • 你只需要捕获 \s : (\d\d-\d\d-\d\d)\s+(\d\d:\d\d(AM|PM ))\s+()?\s+(\d*)\s+([\w\._\-]+\s)*
    • @TonyTheLion Kilazur 所说的,例如。您有很多选择可以到达字符串的末尾。例如 demo 中的 [^\n]* 看起来你正在创建捕获组(不知道为什么,因为你想拆分?)所以你必须决定它是否属于我们的括号外。
    • @TonyTheLion 我的意思是如果你只想匹配行,这可以替换你的整个正则表达式。 ^[^\n]* ...但大概你知道目录应该是什么样子(时间戳等)
    【解决方案3】:

    正确的正则表达式是

    (\d\d-\d\d-\d\d)\s+(\d\d:\d\d(AM|PM))\s+(<DIR>)?\s+(\d*)\s+([\w\._\-]+\s)*
    

    您必须在最后一部分捕获 \s 以避免拆分字符串。

    RegexHero 上测试。 我认为在这个特定示例中您不需要 ^ 和 $。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多