Perl であろうとなかろうと、正規表現の問題は、その欲張りさにある場合があります。誰かの名をキャプチャしたいとしましょう。文字列は次のようになります。
Bob Baker
次の正規表現を使用できます。
sed 's/^\(.*)\ .*$/\1/'
これはBob Bakerでは機能しますが、 Bob Barry Bakerでは機能しません。問題は、私の正規表現が貪欲で、最後のスペースまでのすべての文字を選択することです。これを解決する一般的な方法は、不要な文字を除くすべての文字を指定することです。Bob
Bob Baker
sed 's/^\([^ ]*)\ .*$/\1/'
この場合、スペースを含まない任意の文字セットを指定しています。これにより、Bob Baker
との両方が に変更Bob Rudolph Baker
されますBob
。
Perl には、非貪欲な正規表現を指定する別の方法があります。?
Perl では、貪欲にならないようにする部分式にa を追加します。上記の例では、これらはどちらも次を含む文字列を次のように変更しBob Barry Baker
ますBob
。
$string =~ s/^([^ ]+) .*$/$1/;
$string =~ s/^(.+?) .*$/$1/;
ちなみに、これらは等価ではありません!
スペース正規表現以外のすべてを使用すると、次のことができます。
$string =~ /^([^ ]+)( )(\[\d{4}\])( )(\(\d+p\))(\.)([^.]+)/
貪欲でない修飾子を使用すると、次のようになります。
$string =~ /^(.+?)( )(\[\d{4}\])( )(\(\d+p\))(\.)(.*)/
また、x
修飾子を使用すると、同じ正規表現を複数行に渡って配置できます。コメントを追加して、何をしているのかを説明できるので便利です。
$string =~ /
^(.+?) #Any set of characters (non-greedy)
([ ]) #Space
(\[\d{4}\]) #[1959]
([ ]) #Space
(\([0-9]+p\)) #(430p)
[.] #Period
([^\.]+) #File Suffix (no period)
/x
そして、この時点で、Damian Conway のPerl 正規表現に関するベスト プラクティスの推奨事項に従うこともできます。
$string =~ /
\A #Start of Regular Expression Anchor
( .+? ) #Any set of characters (non-greedy)
( [ ] ) #Space
( \[ \d{4} \] ) #[1959]
( [ ] ) #Space
( \( [0-9] +p \) ) #(430p)
( [.] ) #Period
( [^\.]+ ) #File Suffix (no period)
\Z #End of string anchor
/xm;
すべてx
の空白を無視するため、同じ行のサブグループ間にスペースを追加することもできます。この場合、は よりも少しクリーンです。理解しやすいかどうかは、あなた次第です。( .*+? )
(.*+?)
( \( [0-9] +p \) )
( \( [0-9]+p \) )
( \([0-9]+p\) )
そして、はい、答えはシナンの答えに非常によく似ています。
ちなみに、シナンが示したように、貪欲でない正規表現修飾子a b c d e [1234] (1080p).mov
を使用すると解析できますが、スペース部分式を含まないものはすべて使用できません。だから、私はそれらが同じではないと言いました。