Bash = ~ normal ifade ve https://regex101.com/


13

Https://regex101.com/ kullanarak bir dizede bir IP adresinin ilk oluşumunu döndürmek için düzenli bir ifade oluşturdum.

RegExp:

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

Sınırlayıcılar dahil RegExp:

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

Aşağıdaki test dizesiyle:

eu-west                       140.243.64.99 

Şunun tam eşleşmesini döndürür:

140.243.64.99

Ben çapa vb ne denemek olursa olsun, aşağıdaki bash betiği oluşturulan normal ifade ile çalışmaz.

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
Bana Perl düzenli ifadesi gibi geliyor. Bash bunu desteklemiyor.
Kusalananda

1
=~Operatör tartışılmıştır manuel burada o bash kullanır "genişletilmiş düzenli ifadeler" yazılı nerede. Genişletilmiş normal ifadeler kılavuz regex(7)sayfasında açıklanmıştır ve burada kısaca özetlenmiştir .
glenn jackman

Yanıtlar:


15

\d"herhangi bir rakam" demenin standart dışı bir yoludur. Bence Perl'den geliyor ve diğer birçok dil ve yardımcı program da Perl uyumlu RE'leri (PCRE) destekliyor. (ve örneğin Debian esnemesindeki GNU grep 2.27 \w, normal modda bile kelime karakterleri için benzer olanı destekler .)

Bash \dyine de desteklemediğinden , açıkça [0-9]veya kullanmanız gerekir [[:digit:]]. Olmayan yakalayan grup için aynı (?:..), sadece kullanmak (..)yerine.

Bunun yazdırılması gerekir match:

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

2
GNU'nuz olmadan grepdestekliyor mu? \d-P
Stéphane Chazelas

@ StéphaneChazelas, tabii ki hayır. Destekliyor \wve \bPerl'den öğrendiğim gibi, kafam karıştı.
ilkkachu

1
\dPCRE'nin "standart dışı" olduğunu söylemek gerçekten adil değil . Oldukça standart, orijinal düzenli ifadelerden ve genişletilmiş düzenli ifadelerden farklı bir standart.
Daniel Farrell

1
@DanielFarrell, bu durumda standart POSIX'in belirttiği şeydir ve bilmiyor \d. Bu PCRE'de haklı olmanıza rağmen oldukça standart veya en az iyi tanımlanmış. Rahatsız edici bir sorun, GNU grep (veya glibc) bir PCRE'nin benzeri atomu, en az desteklemesi \wve \sERE yorumlanırken, ve bu bağlamda çok fazla olan standart dışı. İfadem kısmen bundan kaynaklanıyor olabilir ve \dbenzer şekilde GNU destekli yanlış anlaşılma olabilir .
ilkkachu

4

(:...)ve \dperl veya PCRE düzenli ifade operatörleridir (GNU'daki gibi grep -P).

bashyalnızca genişletilmiş düzenli ifadeleri destekler, grep -Eancak [[ text =~ regexp-here ]]tırnaksız bir genişlemenin ( [[ text =~ $var ]]veya olduğu gibi [[ test =~ $(printf '%s\n' 'regexp-here') ]]) tam anlamıyla geçirilen normal ifadeler için POSIX genişletilmiş düzenli ifade özellik seti ile sınırlıdır.

Bu nedenle grep -E '\d', çalışacağı sistemlerde bile (GNU ERE'ler, \sgelecekteki sürümlerin de olabileceği gibi perl regexps'lerinden bazı uzantıları zaten içe aktarmışlardır \d) şunları kullanmanız gerekir:

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

içinde bashçalışması için ( [[ $text =~ \d ]]olmaz).

PCRE'leri destekleyen bir kabuk için, zshbunun yerine kullanmak isteyebilirsiniz :

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

ksh93, desen eşleşmesinin bir parçası olarak perl benzeri düzenli ifadelerin (tam olarak uyumlu olmayan) kendi uygulamasını da destekler. Orada şunu kullanırsınız:

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

( =yerine not edin =~. Geçici değişkenleri kullanmak istemezsiniz, çünkü kullanmadığınız zaman çok buggy olur)


1

Regex101.com sitesi varsayılan olarak PCRE (sol üst köşeye bakın) kullanır ve "Genişletilmiş" normal ifade sözdizimi desteğinden yoksundur. Bu Perl'den (beklendiği gibi makul) gelen "Perl Uyumlu Düzenli İfadeler" dir.

PCRE, grep -Pbazı koşullar altında bazı araçlar (gibi ) tarafından desteklenir , ancak [[…]]deyim içindeki bash regex desteği yalnızca genişletilmiş regex (gibi grep -E) içindir.

Genişletilmiş normal ifade, yakalama olmayan (?…)parantez yok ve \ d de eksik. Basit (…)ve [0-9]şunları kullanmanız gerekir :

regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.