4

Perl の名前変更ユーティリティは、日常のファイル作業、特にプライベートで MP3 コレクションをときどきチェックするときに素晴らしい仕事をします。

一部の人々は、このように常にアーティスト名を大文字にするというひどい習慣を持っています。

03 - ARTIST NAME - Song Title.mp3

このように、もっと落ち着いた見た目の混合ケースに名前を変更してほしい

03 - Artist Name - Song Title.mp3

ただし、これも賢明な方法で行う必要があります。

次のようなフランス語またはイタリア語のタイトルがある場合があります。

05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3

また

07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3

したがって、アーティスト部分のみの後にこれらを大文字と小文字が混在するように変更したくありません。-

うまくいかなかった1つのアプローチは、

rename 's/(\d{1,2} - )([A-Z ]+)([\s\S]+)/$1lc($2)$3/' filename

とにかく投稿しています。なぜなら、私が何をしようとしているのか、常により良い手がかりが得られるからです。

また、を一時変数に置き換えてみました$2が (読み取り専用であるため $2 を変更することは許可されていないため) lc()、結果を出力する前に実行しましたが、成功しませんでした。とにかく、私はかなりのPerl初心者です。

4

2 に答える 2

3

これを行う最も明確な方法は、(修飾子を使用して) 2 段階で評価される/e置換を行うことです。

以下のコードでは、外側の置換により、境界ハイフンを含むアーティスト名が選択され、置換されます。

内側のものは$1- アーティスト名 - を取り、スペース以外の文字のすべてのサブシーケンスを、最初に小文字にしlcて次に大文字にした同じ文字列に置き換えucfirstます。

現状では、プログラムは前後の名前を出力します。#名前を変更するには、名前の行から を削除します。

use strict;
use warnings;

my @data = (
  '05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3',
  '07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3',
);

for my $file (@data) {

  (my $new = $file) =~ s{(-[^-]+-)}{
    (my $artist = $1) =~ s/(\S+)/ucfirst lc $1/eg;
    $artist;
  }e;

  print "$file\n";
  print "$new\n";
  print "\n";
  # rename $file, $new;
}

出力

05 - JEAN BAGUETTE - Honi soit qui mal y pense.mp3
05 - Jean Baguette - Honi soit qui mal y pense.mp3

07 - SIGNORE AL FORNO - Pazzi sono tutti i calciatori.mp3
07 - Signore Al Forno - Pazzi sono tutti i calciatori.mp3

アップデート

別の方法として、ファイル名をハイフンで分割し、2 番目の部分を編集して結合し直すこともできます。

上からのメインループは

for my $file (@data) {

  my @file = split /-/, $file;
  $file[1] =~ s/(\S+)/ucfirst lc $1/eg;
  my $new = join '-', @file;

  print "$file\n";
  print "$new\n";
  print "\n";
  # rename $file, $new;
}

機能と出力は変更されていません。


更新 2

/-.*?-/ を使用して実験し、次に substr($_, $-[0], $+[0]) を =~ s/// の左辺値として使用しましたが、残念ながらうまくいきませんでした

それは私がそれを実験しなければならなかったとても素晴らしいアイデアのように思えました.

とは文字列へのオフセットであるため、への呼び出しsubstrは間違っています。の 3 番目のパラメーターは文字列の長さでなければならないため、次のように記述する必要があります。$-[0]$+[0]substrsubstr($_, $-[0], $+[0] - $-[0])

このコードは正常に機能し、以前と同じ結果が得られます

for my $file (@data) {

  next unless $file =~ /-[^-]+-/;
  my $new = $file;
  substr($new, $-[0], $+[0]-$-[0]) =~ s/(\S+)/ucfirst lc $1/eg;

  print "$file\n";
  print "$new\n";
  print "\n";
  # rename $file, $new;
}
于 2012-06-12T23:03:35.967 に答える
2

ucfirst正規表現で( \u) およびlc( )のエスケープ シーケンスを使用し、\Lさらに先にダッシュを必要とする先読みアサーションと組み合わせることができます。

perl -pe 's/(\w)(\w+)(?=.*-)/\u$1\L$2/g'

より正確にしたい場合は、\pLの代わりに (文字)を使用できます\w。これはrenameツールで動作すると思います。

ETA:\uの代わりに使用するように更新されました\U

于 2012-06-13T00:42:18.900 に答える