これstackoverflow質問は、RFC5322準拠の電子メール形式の一致について次の正規表現を提供します。
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
正規表現には、一致する必要がある単一引用符と二重引用符が含まれています。
これを変数に保存して評価する正確で移植可能なBashメソッドは何ですか?
私のアプローチは、一重引用符を使用し、正規表現の各一重引用符の前に一重引用符部分を終了し、エスケープされた一重引用符を追加し、残りの一重引用符を使用することでした。結果は次のとおりです(元の正規表現に注意してください)'
。数式のすべての内容を次に置き換え、正規表現全体の始めと終わりに'\''
1つを追加します。'
regex='(?:[a-z0-9!#$%&'\''*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'\''*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])'
その後、入力echo $regex
(およびecho "$regex$"
)は元のリンクで定義されているとおりに正規表現文字列を正確に出力します。それから評価してみてください。
if [[ "$email" =~ $regex ]] ; then
echo "This is an RFC5322 compliant e-mail address"
else
echo "This is NOT an RFC5322 compliant e-mail address"
fi
ただし、通常のメールアドレスだけではテストが失敗します。 (使用しても失敗します。)email="[email protected]"
if [[ "$email" =~ "$regex" ]] ; then
問題は何であり、bashでこれを行うための最良かつクリーンな方法は何ですか? (誰かがbashを使用しないようにしたい場合は、残念ながらこれはRFC5322準拠と同様の前提条件です)
答え1
perl
これがinを使って行う方法ですbash
。
- Perlの環境トレイに正規表現を配置します。
- 電子メールアドレスをPerlの標準入力にパイプします。
- その後、Perlで一致し、逆の状態で終了しようとします。なぜなら、bashとPerlは相互に補完的な成功感を持っているからです。
- 休憩はあなたのビジネスです。
printf '%s\n' "$email" \
| _regex_="$regex" \
perl -0777 -ne 'chop;exit !/$ENV{_regex_}/'
if [[ $? == 0 ]] ; then
echo "This is an RFC5322 compliant e-mail address"
else
echo "This is NOT an RFC5322 compliant e-mail address"
fi