Grep'te doğru normal ifade çalışmıyor


13

Bu normal ifade var:

(?<=prefix).*$

"önek" dizesini izleyen herhangi bir karakteri döndürür ve herhangi bir çevrimiçi normal ifade motorunda iyi çalışır (ör. https://regex101.com ). Sorun şu regex bash kullandığınızda:

grep '(?<=prefix).*$' <<< prefixSTRING

hiçbir şeyle uyuşmuyor. Neden bu normal ifade grep ile çalışmıyor?


11
Bu gerçekten regex101'in neden JS, Perl / PHP ve Python için bir POSIX lezzet seçiciye ihtiyacı olduğunu vurgular. Bunun için kaç kez dilediğimi sayamıyorum.
Jared Smith


Ayrıca, .*$herhangi bir dizeyi yalnızca bir karakterle değil, satır sonuna (veya dize sonuna) kadar eşleştirir.
ilkkachu

Yanıtlar:


38

Doğru normal ifadeyi tanımlamış gibisiniz, ancak grepbunu anlamak için komut satırında yeterli bayrakları ayarlamıyorsunuz . Çünkü varsayılan olarak grepBRE'yi destekler ve -Ebayrakla ERE yapar. Sahip olduklarınız (ileriye dönükler) sadece bayrağı grepile sadece GNU'da desteklenen PCRE regex lezzetinde mevcuttur -P.

Yalnızca eşleşen kısmı şu şekilde yazdırdığınızı bildirmek için fazladan bir bayrak eklemeniz gerektiğinde yalnızca eşleşen dizeyi çıkarmanız gerektiğini varsayarsakprefix-ogrep

grep -oP '(?<=prefix).*$' <<< prefixSTRING

Bir versiyonu da vardır grepvarsayılan olarak o destekler PCRE kütüphanelerinde - pcregrephangi sadece yapabileceği

pcregrep -o '(?<=prefix).*$' <<< prefixSTRING

Bu normal Giles'in cevabı ve her birini uygulayan araçlarda çeşitli regex lezzetleri hakkında ayrıntılı açıklama


38

Düzenli ifadeler birçok farklı aromaya sahiptir. Gösterdiğiniz, Perl benzeri bir normal ifadedir (PCRE, "Perl Uyumlu Düzenli İfade").

grepPOSIX düzenli ifadeleri yapar. Bunlar temel normal ifadeler (BRE) ve genişletilmiş düzenli ifadelerdir ( seçenekle grepbirlikte kullanılıyorsa ERE -E). Kılavuzunuzun sisteminizdeki kılavuzuna re_formatveya regexbenzer grepkılavuzlara veya az önce bağlandığım POSIX standart metinlerine bakın.

GNU grepkullanırsanız grep, GNU'ya grepözgü -Pseçenekle kullandıysanız Perl benzeri normal ifadeleri kullanabilirsiniz .

Ayrıca , satırların alt dizeleri değil, varsayılan olarak satırlarıgrep döndürdüğünü unutmayın . Yine, GNU (ve diğer bazı uygulamalar) ile, yalnızca her satırdan verilen ifadeyle eşleşen bit (ler) i almak için bu seçeneği kullanabilirsiniz .grepgrep-o

Her iki Not -Pve -ostandart olmayan uzantıları POSIX özelliklerigrep .

GNU grepkullanmıyorsanız, sedbunun yerine dize prefixile satır sonu arasında bit elde etmek için kullanabilirsiniz :

sed -n 's/.*prefix\(.*\)/\1/p' file

Bunun yaptığı şey, yalnızca sedverilen ikameyi uygulamayı başaran satırları yazdırmaktır . İkame, bir BRE olan ifadeyle eşleşen tüm satırı, dizeden sonra oluşan parçayla değiştirir prefix.

Birkaç örnek vardır eğer Not prefixbir hat üzerinde, sedvaryasyon sonra dize dönecekti son GNU ederken, biri grepvaryasyon sonra dize dönecekti ilk (diğer örneklerini içerir one prefix).

sedSolüsyon tüm Unix benzeri sistemlere taşınabilir olacaktır.


6

Diğer cevapların belirttiği gibi, grepgözetleme özelliklerine sahip bir normal ifade aroması kullanmaz (varsayılan olarak GNU grepile veya diğer sürümlerle hiç).

Kendinizi GNU kullanamıyorsanız grepveya varsa pcregrepkullanabilirsiniz perl.

İle eşdeğer olan komut satırı şöyledir perl:

perl -ne 'print if /(?<=prefix).*$/' <<< prefixSTRING

Eğik çizgiler arasına istediğiniz normal ifadeyi koydunuz. Perl'i kullandığınızda, bu Perl'in regex lezzetini kullanır .


ya da print "$&\n" if ...sonra sadece bir kısmını prefix
çıkarmak istiyorlarsa
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.