Ruby 提取包含和不包含终止字符的文件名

Ruby 提取包含和不包含终止字符的文件名,ruby,regex,Ruby,Regex,我有一个字符串,它将包含以下文本之一: 内联;filename=“name.extension” 内联;filename=“name.extension” 内联;filename='name.extension' 内联;filename='name.extension' 内联;filename=name.extension 内联;filename=name.extension 我想提取name.extension,可以处理前5个案例,但我不知道如何用一个正则表达式处理所有案例。我尝试的一切都变得

我有一个字符串,它将包含以下文本之一:

  • 内联;filename=“name.extension”
  • 内联;filename=“name.extension”
  • 内联;filename='name.extension'
  • 内联;filename='name.extension'
  • 内联;filename=name.extension
  • 内联;filename=name.extension
  • 我想提取name.extension,可以处理前5个案例,但我不知道如何用一个正则表达式处理所有案例。我尝试的一切都变得太贪婪了。这可能吗

    适用于前5个版本的正则表达式是:

    /filename=["']?(.*)(?=["']?;)/
    
    name.extension位于第一个捕获组中,在linux中必须允许文件名使用任何有效字符。这包括“和”和;在内

    谢谢您的帮助!

    试试这个:

    /filename=["']?([^"';]+)/
    
    它应该返回第一个捕获组中的字符串

    [
      'inline; filename="name.extension";',
      'inline; filename="name.extension"',
      "inline; filename='name.extension'",
      "inline; filename='name.extension';",
      "inline; filename=name.extension;",
      "inline; filename=name.extension"
    ].map { |str| str[/filename=["']?([^"';]+)/, 1] == "name.extension" }
    
     => [true, true, true, true, true, true] 
    

    保持它的简单性和可维护性,不要使用正则表达式:

    arr = %q(inline; filename="name.extension";
    inline; filename="name.extension"
    inline; filename='name.extension';
    inline; filename='name.extension'
    inline; filename=name.extension;
    inline; filename=name.extension).lines.map(&:chomp)
    
    p arr.map{|str|  str.delete(%q("';) ).split("=").last}
    
    这利用了ruby灵活的字符串文字语法;这里使用了两次%q()技巧,可以轻松地处理单引号和双引号。

    分三个阶段进行

  • 上拆分以分隔语句
  • =
    上拆分键/值对
  • 处理价值的引用
  • 这里有一个基本的例子

    def get_value(line)
        # Split into statements
        statements = line.split(/\s*;\s*/)
    
        # Extract the value of the 2nd statement
        _,value = statements[1].split(/\s*=\s*/)
    
        # Strip the quotes
        value.gsub!(/^(['"]?)(.*)\1$/, '\2')
    
        return value
    end
    
    有一些边缘情况无法处理:如果您感兴趣的语句不是第二个语句怎么办?但可以根据需要进行修复。当解析分多个步骤完成时,改进解析比将其塞进一个正则表达式要容易得多

    例如,这可以正确地处理嵌入的和转义的引号,如
    %q[inline;filename=“name's.extension”]
    %q[inline;filename=“name's.\\”extension\\\\\][/code>


    如果你真的想把它作为一个正则表达式,好吧,你自找的

    re = /
        \bfilename
        \s*=\s* 
        (?:
            (?<quote>['"])(?<value>.*)\k<quote> |
            (?<value>[^;]+)
        )
    /x
    return re.match(line)['value']
    
    re=/
    \B文件名
    \s*=\s*
    (?:
    (?['“])(?.*)k|
    (?[^;]+)
    )
    /x
    返回重新匹配(行)['value']
    
    这将扩展的处理分为两种选择:一种带引号,另一种不带引号。否则
    filename=name.ext
    将拾取分号,我无法找到另一种不引入新问题的方法来阻止它

    例如,
    /\bfilename\s*=\s*(?['“])(?.*?)\k;?$/
    将用于测试数据,但如果分号后面有任何内容,例如
    %q[inline;filename='name.extension';foo]
    ,则会失败


    您要求获得专业的正则表达式知识。成为正则表达式专家的一部分是要知道何时不应该使用正则表达式。这可能需要用语法来处理,否则您将不断地处理边缘情况。

    这在给定的集合上有效,但在内部引号(如
    %q[inline;filename=“name's.extension”)上失败
    这就是为什么这样做很困难(至少对我来说是这样)。我不控制文件名,因此它可以包含单引号或双引号以及分号。这就是为什么我使用正向前瞻,但它不处理任何一种情况。这将去掉任何嵌入的引号,如
    内联;filename=“name”s.extension";
    内联;filename=“name.\“extension\”
    @Schwern是的,但无论如何,这些文件名都是可疑的。这违反了规则。由于引号已被删除,这甚至可能是一个安全问题,留下一个开口诱使进程读取另一个文件。@steenslag可能不确定,但我不控制文件名,而且旁边是合法字符。到目前为止,没有一个答案能识别不平衡的引号,例如前面有一个引号,后面没有引号。你想用这个方法来确认引用(如果存在的话)是平衡的吗?事实上,这是蛋糕上的樱桃:-)在某一点上,你需要一个语法。是的,我可以用代码来解决它,但我真的很好奇,想看看是否有具有专业正则表达式知识的人可以解决这个问题。如果答案是正则表达式不能覆盖所有的情况,那么我会回到编程上来。我正试图用回形针修补一些东西,最简单的方法就是简单地修复正则表达式。@Whyves我用一个正则表达式编辑了它,但正如你所看到的,它有点讨厌。如果你是这个意思,我不明白为什么不能用函数调用替换正则表达式。也许你应该问一个关于你想修补什么的问题。好吧,你已经明确表达了你的观点:-)我也相信可读性和可维护性。然而,我必须为正则表达式说声“哇”。至于回形针,这不是问题,我将使用一个函数。只是它目前对“内容处置”标题有错误,因为我遇到了边缘情况。目前它是用正则表达式处理的,所以最简单的方法就是修复这一行代码。非常感谢您花时间和精力回答这个问题@为什么不客气!是的,HTTP头肯定应该被解析,而不是regexed(现在这是动词吗?),您还需要看一下。我希望我能推荐一门好的Ruby语法课。你可以用一系列的正则表达式来重现语法,尽管我不知道它有多好。你的正则表达式指出了命名捕获组的优点,这是我以前没有考虑过的:两个组可以被赋予相同的名称。