代码之家  ›  专栏  ›  技术社区  ›  Matt McManis

选择句点,但不选择带小数点的数字元素

  •  0
  • Matt McManis  · 技术社区  · 4 年前

    我正在尝试使用 regex 在里面 C# 在文件名上,选择句点 . 并用空格替换它们 .

    https://regex101.com/r/HfZPLo/3

    但是,我想保留某些可能包含小数点的数字元素:

    2CH
    5.1CH 
    DTS5.1
    DD7.1
    
    123k
    123.5k
    1300.5K
    
    60fps
    23.976fps
    29.97fps
    
    48kHz
    22.05kHz
    44.1kHz
    

    文件名示例

    File.x264.CRF32.23.976fps.AAC.DTS5.1.123.5k.44.1kHz
    
    File.x264.CRF32.29.97fps.AAC.DD7.1.123.5k.22.05kHz
    
    File.x264.CRF32.23.976fps.AAC.5.1CH.123.5k.44.1kHz
    
    File.x264.CRF32.23.976fps.AAC.5.1.Dolby.123.5k.44.1kHz
    

    正则表达式规则

    (?<!\.DTS|\.\d\d\d\d\d\d|\.\d\d\d\d\d|\.\d\d\d\d|\.\d\d\d|\.\d\d|\.\d)(\.)(?!CH\.|\d\.|fps\.|kHz\.|k\.|m\.)
    

    我似乎无法获得所有负面展望和展望来捕捉所有元素。有时一个会覆盖另一个,例如 DTS5.1 123.5k 他们彼此相邻。

    此外,如果这些文件名标签是按任何顺序排列的,它也需要工作。


    期望结果

    File x264 CRF32 23.976fps AAC DTS5.1 123.5k 44.1kHz
    
    File x264 CRF32 29.97fps AAC DD7.1 123.5k 22.05kHz
    
    File x264 CRF32 23.976fps AAC 5.1CH 123.5k 44.1kHz
    
    File x264 CRF32 23.976fps AAC 5.1 Dolby 123.5k 44.1kHz
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   Wiktor Stribiżew    4 年前

    您可以使用

    var result = Regex.Replace(text, @"(?<!CRF\d*)(\d\.\d)|\.", m => m.Groups[1].Success ? m.Groups[1].Value : " ")
    

    这个 (?<!CRF\d*)(\d\.\d)|\. 正则表达式将匹配并捕获任何 digit.digit 前面没有 CRF 以及任意数量的数字,或者在任何其他上下文中只匹配一个点,以及 Regex.Replace 如果组1匹配,将用组1的内容替换匹配项,否则将用空格替换匹配项。

    所以,上面的代码实际上意味着 如果点不在两位数字之间,则用空格替换任何点,除非初始数字前面有 CRF .

    请参阅 C# demo :

    var strs = new List<string> { "File.x264.CRF32.23.976fps.AAC.DTS5.1.123.5k.44.1kHz","File.x264.CRF32.29.97fps.AAC.DD7.1.123.5k.22.05kHz","File.x264.CRF32.23.976fps.AAC.5.1CH.123.5k.44.1kHz","File.x264.CRF32.23.976fps.AAC.5.1.Dolby.123.5k.44.1kHz"};
    //var m_pat = @"\bCRF\d+|[A-Za-z]+(?:\d+(?:\.\d+)?)?|\d+(?:\.\d+)?[a-zA-Z]*";
    foreach (var s in strs) 
    {
        Console.WriteLine(Regex.Replace(s, @"(?<!CRF\d*)(\d\.\d)|\.", m => m.Groups[1].Success ? m.Groups[1].Value : " "));
        //Console.WriteLine(string.Join(" ", Regex.Matches(s, m_pat).Cast<Match>().Select(x => x.Value)) );
    }
    

    输出:

    File x264 CRF32 23.976fps AAC DTS5.1 123.5k 44.1kHz
    File x264 CRF32 29.97fps AAC DD7.1 123.5k 22.05kHz
    File x264 CRF32 23.976fps AAC 5.1CH 123.5k 44.1kHz
    File x264 CRF32 23.976fps AAC 5.1 Dolby 123.5k 44.1kHz
    

    注意,我添加了另一个, 匹配、提取然后连接 解决方案,但似乎更长。那里的图案意味着匹配

    • \bCRF\d+ -整个单词 CRF abd 1+位数字
    • | -或
    • [A-Za-z]+(?:\d+(?:\.\d+)?)? -1+个字母和一个可选的整数/浮点数
    • | -或
    • \d+(?:\.\d+)?[a-zA-Z]* -一个浮点数/int,然后是0+个字母。