一方:
$ shopt -s extglob
$ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )}<<"
>> abcdefg<<
文字「a」の前にスペースがあるのはなぜですか?二度目も*( )
空間にふさわしくしたかったのですが、そうするには適していませんね。
私は次の結果を期待しています:
$ echo ">>$(echo -n "${TEST}" | perl -pe "s/^ *z *//g")<<"
>>abcdefg<<
*( )
次の文字(「a」など)を指定すると、2番目の文字が一致します。
$ shopt -s extglob
$ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )a}<<"
>>bcdefg<<
ヒットバージョン: GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
答え1
${TEST#...}
最も短い文字列、zの後にスペースがない文字列と一致します。あなたは${TEST##...}
最長のマッチが欲しいです。
答え2
これは、貪欲ではない部分文字列の削除と使用中のパターンの種類との相互作用が原因で発生します。
~からバッシュマニュアル、
?(pattern-list)
指定されたパターンが0個または1個一致します。
*(pattern-list)
指定されたパターンのゼロ以上の発生と一致します。
+(pattern-list)
与えられたパターンと1つ以上一致します。
私が好きなbashの説明から文字列演算、
${string#substring}
$substring
以前に最も短い一致を削除します$string
。
${string##substring}
$substring
最も長い前の一致を削除します$string
。
したがって、 を指定するときは、次のように${TEST#*( )z*( )}
言うことです。 「ゼロ個以上のスペースがある最短の部分文字列aを削除し、z
その後にゼロ個以上のスペースが続きます。
最後の空白がある一致はない項目よりも長いため、最後の空白は一致しません。
この問題を解決するには、${TEST##*( )z*( )}
ゼロを超えるスペースで終わる最長のプレフィックス一致を使用するか、${TEST#*( )z+( )}
1つ以上のスペースで終わる最短のプレフィックス一致を使用できます(1つのスペースで終わる最短のプレフィックス一致と機能的に同じです)。
答え3
is(perl)正規表現を模倣するには、regex
not aを使用しますpattern
。
$ test=" z abcdefg"
$ regex='^ *z *(.*)'
$ [[ $test =~ $regex ]]
$ echo ">>${BASH_REMATCH[1]}<<"
>>abcdefg<<
正規表現は完全なPCREではなく拡張正規表現です。