0

ファイル名のプレフィックスが発生するインスタンスの数をカウントするために、ファイル名を解析するための正規表現を探しています。ここにいくつかのサンプル文字列があります

手袋.tga
10ジーンズ.jpg
シャツ1.png
シャツ2.png
coat_00.png
coat_12.gif
top1_01.png
top2_04.png

基本的なパターンは、文字または数字の文字列とそれに続く拡張子です。プレフィックスは拡張子の前のすべてです (ピリオドを除く)

1 つの衣類が複数のファイルにまたがっている場合があります。これは、衣類の名前、アンダースコア、インデックス番号、拡張子で示されます。プレフィックスはアンダースコアまでのすべてですが、アンダースコアは含みません。それ以外はすべて無視できます。

これは私が扱っているすべてのケースをカバーしていますが、あるケースにはアンダースコアがあり、他のケースにはないという事実に対処するのに問題があります。

誰かがこれの正規表現を考え出すのを手伝ってくれますか?

編集: 追加の条件があるようです: shirt1 と shirt2 は同じプレフィックスとして扱われるべきです。

したがって、文字列の後にいくつかの数字が続き、その直後に拡張子が続く場合、数字は無視されますが、数字の後にアンダースコアが続く場合、それらはプレフィックスに保持されます。

4

1 に答える 1

2

これはうまくいきませんか?(Perl/PCRE 構文)

/^([^._]+)/ 

これにより、ピリオドやアンダースコアを含まない文字列の最長のプレフィックスが取得されます。

編集: OK、shirt接頭辞が の場合、次のshirt1ようなものを試すことができます:

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

これは、数字で終わる接頭辞を許可しません。ただし、1.8 には後読みアサーションがないため、これは Ruby 1.8 では機能しません。

EDIT 2 : 上記は、のプレフィックスが であることを意味しますがtop1_01topアンダースコアの前に数字を含める必要があります。したがって、最後の試みは代替手段を追加することです。

/^([^._]+)(?:(?<!\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 に答える