我正在寻找一些文件名解析的正则表达式,以便计算文件名前缀出现的实例数。以下是一些示例字符串
gloves.tga 10jeans.jpg shirt1.png shirt2.png coat_00.png coat_12.gif top1_01.png top2_04.png
基本模式只是一串字母或数字后跟一个扩展名。前缀是扩展名之前的所有内容(不包括句点)
单件衣服可以分布在多个文件中,由服装名称表示,后跟下划线,后跟一些索引号,然后是扩展名。前缀是一切,但不包括下划线。其他一切都可以被忽略。
这涵盖了我正在使用的所有案例,但是我无法处理一个案例有下划线而另一个案例没有下划线的事实。
有人可以帮我提出一个正则表达式吗?
编辑:似乎有一个额外的条件:shirt1和shirt2应被视为相同的前缀。
因此,如果一个字符串后跟一些数字,然后紧跟一个扩展名,那么这些数字应该被忽略,而如果这些数字后跟一个下划线,那么它们将保留在前缀中。
答案 0 :(得分:2)
这不会起作用吗? (Perl / PCRE语法)
/^([^._]+)/
这将捕获不包含句点或下划线的字符串的最长前缀。
编辑:好的,如果shirt
是[{1}}中的前缀,那么你可以尝试这样的事情:
shirt1
不允许以数字结尾的前缀。但是,这不适用于Ruby 1.8,因为1.8没有lookbehind断言。
编辑2 :
以上意味着/^([^._]+)(?<!\d)/
的前缀为top1_01
,但我们希望该前缀包含下划线之前的数字。所以我们最后的尝试是添加一个替代方案:
top
前缀必须 不以数字结尾或后跟下划线。 演示:
/^([^._]+)(?:(?<!\d)|(?=_))/
输出:
%w<gloves.tga 10jeans.jpg shirt1.png shirt2.png
coat_00.png coat_12.gif top1_01.png top2_04.png>.each do |filename|
if m = filename.match(/^([^._]+)(?:(?<!\d)|(?=_))/) then
puts [ filename, m[1] ].join ":\t"
else
warn "Uh-oh, couldn't find a prefix in filename '#{filename}'."
end
end