正規表現を使用して文字列の一部を抽出したいです。たとえば、変数からドメイン名を抽出するにはどうすればよいですか$name
?
name='<A HREF="http://www.google.com/">here</A>'
domain_name=... # apply some regex on $name
ベストアンサー1
使用bash 正規表現:
re="http://([^/]+)/"
if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]}; fi
編集- OP は構文の説明を求めました。正規表現の構文これは大きなトピックなので、ここですべてを説明することはできませんが、例を理解するのに十分な説明を試みます。
re="http://([^/]+)/"
これは bash 変数に格納される正規表現です。re
つまり、入力文字列と一致させ、できれば部分文字列を抽出したいものです。詳しく見てみましょう:
http://
単なる文字列です - 正規表現が一致するには、入力文字列にこの部分文字列が含まれている必要があります[]
通常、角括弧は「括弧内の任意の文字に一致する」という意味で使用されます。つまり、c[ao]t
「cat」と「cot」の両方に一致します。^
角括弧内の文字は[]
これを「任意の文字に一致する」という意味に変更します。を除外する角括弧内の文字です。したがって、この場合は[^/]
「/」以外の任意の文字と一致します。- 角括弧式は 1 つの文字のみに一致します。
+
末尾に a を追加すると、「先行する部分式の 1 個以上に一致」することを意味します。つまり、[^/]+
「/」を除くすべての文字セットの 1 個以上に一致します。 - 部分式を括弧で囲む
()
と、その部分式に一致したものを後で処理するために保存することを意味します。使用している言語がこれをサポートしている場合は、これらの部分一致を取得するための何らかのメカニズムが提供されます。bash の場合、それは BASH_REMATCH 配列です。 - 最後に、「/」の完全一致を行い、完全修飾ドメイン名の最後までと、それに続く「/」が一致することを確認します。
次に、入力文字列を正規表現と照合して一致するかどうかをテストする必要があります。これを行うには、bash 条件文を使用します。
if [[ $name =~ $re ]]; then
echo ${BASH_REMATCH[1]}
fi
bash では、[[ ]]
拡張条件テストを指定し、=~
bash 正規表現演算子を含めることができます。この場合、入力文字列が$name
正規表現 に一致するかどうかをテストします$re
。一致した場合、正規表現の構造により、(括弧 から()
) サブマッチがあることが保証され、BASH_REMATCH 配列を使用してアクセスできます。
- この配列の要素0
${BASH_REMATCH[0]}
は、正規表現に一致する文字列全体、つまり「http://www.google.com/「」。 - この配列のその後の要素は、サブマッチの後続の結果になります。
()
正規表現内に複数のサブマッチを含めることができることに注意してください。BASH_REMATCH
要素は順番にこれらに対応します。したがって、この場合は${BASH_REMATCH[1]}
「www.google.com」が含まれますが、これが必要な文字列だと思います。
BASH_REMATCH配列の内容は、正規表現=~
演算子が最後に使用されたときにのみ適用されることに注意してください。したがって、さらに正規表現の一致を実行する場合は、しなければならない毎回この配列から必要な内容を保存します。
これは長い説明のように思われるかもしれませんが、正規表現の複雑な点のいくつかをざっと説明しただけです。正規表現は非常に強力で、パフォーマンスもそれなりにあると思いますが、正規表現の構文は複雑です。また、正規表現の実装はさまざまであるため、言語が異なればサポートされる機能も異なり、構文に微妙な違いがある場合があります。特に、正規表現内の文字のエスケープは、その文字が特定の言語で異なる意味を持つ場合など、厄介な問題になることがあります。
$re
変数を別の行に設定して条件でこの変数を参照する代わりに、正規表現を条件に直接入れることもできます。ただし、バッシュ3.2、このようなリテラル正規表現を引用符で囲む必要があるかどうかに関するルールが変更されました。正規表現を別の変数に配置すると、この問題を簡単に回避でき、一致演算子をサポートするすべての bash バージョンで条件が期待どおりに機能します=~
。