0

ディレクトリ内の一連のファイルの名前を変更しようとしていますが、その正規表現部分で立ち往生しています。

ファイル名の先頭にある特定の文字を削除したい。

例1:_00-author--book_revision_

期待される:Author - Book (Revision)

これまでのところ、正規表現を使用してアンダースコアを削除し、最初の文字を大文字にすることができます

$newfile =~ s/_/ /g;
$newfile =~ s/^[0-9]//g;
$newfile =~ s/^[0-9]//g;
$newfile =~ s/^-//g;
$newfile = ucfirst($newfile);

これは良い方法ではありません。最初の文字にヒットするまですべての文字を削除するのに助けが必要です.最初の「-」にヒットすると、「-」の前後にスペースを追加したいと思います. また、2 番目の「-」を押すと、「(」に置き換えたいと思います。

正しいアプローチを取るためのガイダンス、ヒント、または提案さえも大歓迎です。

4

4 に答える 4

1
$filename =~ s,^_\d+-(.*?)--(.*?)_(.*?)_$,\u\1 - \u\2 (\u\3),;

私の Perl インタープリター (strict と warnings を使用) によると、これは次のように記述したほうがよいとのことです。

$filename =~ s,^_\d+-(.*?)--(.*?)_(.*?)_$,\u$1 - \u$2 (\u$3),;

最初のものは、おそらくその味のためにもっとセディッシュです! (もちろん、どちらのバージョンもまったく同じように動作します。)

説明 ( stemaの要求による):

$filename =~ s/
  ^       # matches the start of the line
  _\d+-   # matches an underscore, one or more digits and a hypen minus
  (.*?)-- # matches (non-greedyly) anything before two consecutive hypen-minus
          #   and captures the entire match (as the first capture group)
  (.*?)_  # matches (non-greedyly) anything before a single underscore and
          #  captures the entire match (as the second capture group)
  (.*?)_  # does the same as the one before (but captures the match as the
          #  third capture group obviously)
  $       # matches the end of the line
/\u$1 - \u$2 (\u$3)/x;

in replacement 指定は\u${1..3}、最初の文字を大文字にして 1 から 3 までのキャプチャ グループを挿入するように Perl に指示するだけです。(キャプチャされたグループ内の) 一致全体を大文字にしたい場合は、\U代わりに使用する必要がありました。

xフラグは冗長モードをオンにし、 #コメントを使用したいことを Perl インタープリターに伝えるので、これら (および正規表現内のすべての空白 - したがって、スペースに一致させたい場合は、またはのいずれ\sかを使用する必要があります) \)。残念ながら、* replacement* 仕様で空白を無視するように Perl に指示する方法がわかりませんでした。これが、1 行で記述した理由です。

s(また、ターミネータを から,に変更したことにも注意してください-詳細モードをオンにして/使用すると、Perl は私に吠えました ... 正確な理由はわかりません。),

于 2012-05-02T06:05:31.720 に答える
1

あなたの指示とあなたの例は一致しません。

ご指示によると、

s/^[^\pL]+//;    # Remove everything until first letter.
s/-/ - /;        # Replace first "-" with " - "
s/-[^-]*\K-/(/;  # Replace second "-" with "("

あなたの例によると、

s/^[^\pL]+//;
s/--/ - /;
s/_/ (/;
s/_/)/;
s/(?<!\pL)(\pL)/\U$1/g;
于 2012-05-02T05:58:32.690 に答える
1

新しいファイル名のすべてのコンポーネントを大文字にしますか、それとも最初のファイルだけを大文字にしますか? あなたの質問はその点で矛盾しています。

Linux を使用している場合はrename、perl 式を取得し、それを使用してファイルの名前を変更する次のようなコマンドがある可能性があります。

rename 'my ($a,$b,$r);$_ = "$a - $b ($r)" 
  if ($a, $b, $r) = map { ucfirst $_ } /^_\d+-(.*?)--(.*?)_(.*?)_$/' _*
于 2012-05-02T06:18:58.343 に答える
0

それらがすべてその形式に従っている場合は、次を試してください。

my ($author, $book, $revision) = $newfiles =~ /-(.*?)--(.*?)_(.*?)_/;

print ucfirst($author ) . " - $book ($revision)\n";
于 2012-05-02T06:02:56.657 に答える