0

我正在寻找一些文件名解析的正则表达式,以计算出现文件名前缀的实例数。这是一些示例字符串

手套.tga
10牛仔裤.jpg
衬衫1.png
衬衫2.png
外套_00.png
外套_12.gif
top1_01.png
top2_04.png

基本模式只是一串字母或数字,后跟一个扩展名。前缀是扩展名之前的所有内容(不包括句点)

一件衣服可能分布在多个文件中,由衣服名称表示,后跟下划线,后跟一些索引号,然后是扩展名。前缀是所有内容,但不包括下划线。其他的都可以忽略。

这涵盖了我正在处理的所有案例,但是我在处理一个案例有下划线而另一个案例没有的事实时遇到了麻烦。

有人可以帮我想出一个正则表达式吗?

编辑:似乎有一个额外的条件: shirt1 和 shirt2 应该被视为相同的前缀。

因此,如果一个字符串后面跟着一些数字,并且紧跟着一个扩展名,那么这些数字应该被忽略,而如果数字后面跟着一个下划线,那么它们将被保留在前缀中。

4

1 回答 1

2

这行不通吗?(Perl/PCRE 语法)

/^([^._]+)/ 

这将捕获不包含句点或下划线的字符串的最长前缀。

编辑:好的,如果shirt是前缀shirt1,那么你可以尝试这样的事情:

/^([^._]+)(?<!\d)/

这不允许以数字结尾的前缀。但是,这在 Ruby 1.8 中是行不通的,因为 1.8 没有后向断言。

编辑 2:以上表示top1_01is的前缀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    

输出:

 gloves.tga:    gloves
 10jeans.jpg:   10jeans
 shirt1.png:    shirt
 shirt2.png:    shirt
 coat_00.png:   coat
 coat_12.gif:   coat
 top1_01.png:   top1
 top2_04.png:   top2
于 2012-05-25T05:05:41.917 回答