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位于第一个捕获组中,在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语法课。你可以用一系列的正则表达式来重现语法,尽管我不知道它有多好。你的正则表达式指出了命名捕获组的优点,这是我以前没有考虑过的:两个组可以被赋予相同的名称。