Bash =〜regexおよびhttps://regex101.com/


12

https://regex101.com/を使用して、文字列内の最初のIPアドレスを返す正規表現を作成しました。

RegExp:

(?:\d{1,3}\.)+(?:\d{1,3})

区切り文字を含むRegExp:

/(?:\d{1,3}\.)+(?:\d{1,3})/

次のテスト文字列で:

eu-west                       140.243.64.99 

次の完全一致を返します。

140.243.64.99

アンカーなどで何を試しても、次のbashスクリプトは生成された正規表現では機能しません。

temp="eu-west                       140.243.64.99            "
regexp="(?:\d{1,3}\.)+(?:\d{1,3})"
if [[ $temp =~ $regexp ]]; then
  echo "found a match"
else
  echo "No IP address returned"
fi

3
これは、Perlの正規表現のように見えます。Bashはそれをサポートしていません。
クサラナンダ

1
=~オペレータが議論されたマニュアルで、ここでそれは、bashの使い方「拡張正規表現」を書かれています。拡張正規表現はregex(7)manページで説明されており、ここで簡単に要約されています
グレンジャックマン2018

回答:


15

\d「任意の数字」を言うための非標準的な方法です。私はそれがPerlから来ていると思います、そして他の多くの言語とユーティリティもPerl互換のRE(PCRE)をサポートしています。(たとえば、DebianストレッチのGNU grep 2.27は\w、ノーマルモードであっても、ワード文字の同様のものをサポートしています。)

\dただし、Bashはをサポートしていないため、明示的に[0-9]orを使用する必要があります[[:digit:]]。非キャプチャグループについても同じですが、代わり(?:..)に使用し(..)てください。

これは印刷する必要がありますmatch

temp="eu-west                       140.243.64.99            "
regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
[[ $temp =~ $regexp ]] && echo match

2
あなたのGNU grepサポートはあり\dませ-Pんか?
ステファンChazelas

@StéphaneChazelas、おっと、もちろん違います。Perlから学んだとをサポート\wしている\bので、混乱しました。
ilkkachu

言うことは本当に公平ではない\dか、またはPCREは「非標準」です。それらは非常に標準的であり、元の正規表現や拡張正規表現とは異なる標準です。
ダニエルファレル

1
@DanielFarrell、この場合の標準はPOSIXで指定されているものであり、についてはわかりません\d。PCREはかなり標準的であるか、最も明確に定義されていないという点であなたは正しいのですが。迷惑な問題は、少なくとも、GNU grepの(またはglibcでは)は、いくつかのPCREのような原子をサポートしていることである\w\sEREを解釈するとき、その文脈で、彼らは非常に多くある非標準。私の言い回しは、その一部と、\dGNUでサポートされた同様の誤解から生じる可能性があります。
ilkkachu

4

(:...)また\d、perlまたはPCREの正規表現演算子です(GNUと同様grep -P)。

bashのように拡張正規表現のみをサポートします。grep -Eただし[[ text =~ regexp-here ]]、引用符で囲まれてい[[ text =~ $var ]]ない展開の結果(または[[ test =~ $(printf '%s\n' 'regexp-here') ]])とは対照的に、文字どおりに渡される正規表現は、POSIX拡張正規表現機能セットに限定されます。

したがって、grep -E '\d'が機能するシステムでも(GNU EREは、perl正規表現からいくつかの拡張機能をすでにインポートしている\sため、将来のバージョンで\dも同様になる可能性があります)、以下を使用する必要があります。

regexp='\d'
[[ $text =~ $regexp ]]

bashそれが機能するために([[ $text =~ \d ]]そうしません)。

PCREをサポートするシェルの場合は、zsh代わりに使用することをお勧めします。

set -o rematchpcre
[[ $text =~ '(?:\d{1,3}\.)+(?:\d{1,3})' ]]

ksh93は、パターンマッチングの一部として、perlのような正規表現(完全には互換性がない)の独自の実装もサポートしています。そこで、あなたは使うでしょう:

regexp='~(P)(?:\d{1,3}\.)+(?:\d{1,3})'
[[ $text = $regexp ]]

(の=代わりに注意してください=~。一時変数を使用することをお勧めします。そうしないと非常にバグが多いためです)。


1

サイトregex101.comはデフォルトとしてPCRE(左上隅を見てください)を使用しており、「拡張」正規表現構文のサポートが不足しています。それが「Perl互換の正規表現」であり、Perlから(当然のことながら)Perlに由来しています。

PCREは、いくつかのツール(などgrep -P)によって特定の条件下でサポートされますが、[[…]]イディオム内のbash正規表現のサポートは、拡張正規表現(などgrep -E)に対してのみです。

拡張正規表現では、非キャプチャ(?…)括弧が存在せず、\ dもありません。あなたは、単純なを使用する必要がある(…)[0-9]

regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.