[\ W] +, sed içindeki normal ifadede nasıl kullanılır?


24

Windows'tayım, ancak sorum hala doğru bir şekilde buraya yerleştirilmiş.

C:\Users\User>grep --version
GNU grep 2.6.3

C:\Users\User>sed --version
GNU sed version 4.2.1

Aşağıdakilerin işe yaradığını (çıktı here) fark ettim :

echo here | grep -E "\w+"
echo here | grep -E "[her]+"

Ancak bu çalışmaz (hiçbir şey çıkmaz):

echo here | grep -E "[\w]+"

Bu yine yapar (çıktı here):

echo here | grep -P "[\w]+"

Yani [\w]Perl düzenli ifadeler şey özgüdür sanırım. Bu doğru mu?

Öyleyse konuşalım sed. Bu çalışır (çıktı gone):

echo here | sed -r "s/\w+/gone/"
echo here | sed -r "s/[her]+/gone/"

Ve yine, bu (çıkış here) yapmaz :

echo here | sed -r "s/[\w]+/gone/"

Şimdi, Perl için düzenli ifadeleri sed için nasıl etkinleştirebilirim - herhangi bir yolu var mı?

Yanıtlar:


11

Farklı araçlar ve sürümleri, normal ifadelerin farklı biçimlerini destekler. Her birinin belgeleri size neyi desteklediklerini söyleyecektir.

Standartlar mevcuttur, böylece tüm uygun uygulamalarda mevcut olan minimum özellik setine güvenilebilir.

Örneğin, POSIX tarafından belirtilen temel düzenli ifadelerin tüm modern uygulamaları sedve grepuygulaması (en azından bir versiyon veya standardın diğer, ancak bu standart son birkaç on yılda bu konuda çok fazla gelişme sağlamamıştır).

POSIX BRE ve ERE'de [:alnum:]karakter sınıfınız vardır. Bu, yerel ayarınızdaki harf ve rakamlarla eşleşir ( a-zA-Z0-9yerel ayar C olmadığından çok daha fazlasını içerdiğini unutmayın ).

Yani:

grep -x '[[:alnum:]_]\{1,\}'

bir veya daha fazla şapla eşleşir veya _.

[\w]POSIX tarafından gerekli ya ters eğik çizgi maç veya w. Dolayısıyla, uygun olan yerlerde bir uygulama grepveya seduygulama bulamazsınız (standart olmayan seçenekler olmadan).

\wYalnız için davranış POSIX tarafından belirtilmez, bu nedenle uygulamaların istediklerini yapmalarına izin verilir. GNU grepbunu uzun zaman önce ekledi.

GNU grepkendi regexp motoruna sahipti, ancak şimdi GNU libc'sini kullanıyor (kendi kopyasını yerleştirmesine rağmen).

Yerel ayarlarınızda alnumlarla eşleşmek ve alt çizgi çizmek içindir. Bununla birlikte, şu anda yalnızca tek baytlık karakterlerle eşleşmesi gibi bir hatadır (örneğin, açıkça bir mektup olmasına rağmen é'nin tek olduğu tüm yerlerde é ile eşleşmesine rağmen, é bir UTF-8 yerel ayarında değil) karakter).

Ayrıca \wperge regexp ve PCRE de bir regexp operatörü var. PCRE / perl POSIX normal ifadeleri değildir, hepsi bir arada başka bir şeydir.

Şimdi, GNU grep -PPCRE’yi kullanma yöntemiyle , bununla aynı sorunu çözdü -P. Kullanarak (*UCP)(bu UTF8 dışındaki yerlerde de yan etkileri de olsa) kullanarak da çalışabilir .

GNU sedayrıca GNU libc'nin regex'lerini kendi regexps'leri için kullanır. GNU ile aynı böceğe sahip olmamasına rağmen onu öyle kullanıyor grep.

GNU sedPCRE'leri desteklemiyor. Kodunda daha önce denenmiş olduğuna dair bazı kanıtlar var, ancak artık gündemde görünmüyor.

Perl'in düzenli ifadelerini istiyorsanız, sadece kullanın perl.

Aksi taktirde, sizin sed/ uygulamanızın standart dışı bir özelliğine bağlı olan sahte bir özelliğe güvenmek yerine, standarda uymanın grepve kullanmanın daha iyi olacağını söyleyebilirim [_[:alnum:]].


[_[:alnum:]][\w/]( [_[:alnum:]/]bu durumda) olduğu gibi genişletmeme izin veren güzel bir çözüm .
BERS

1
Bu cevap, GNU’nun sınırlamaları bakımından artık modası geçmiş durumda grep.
Stéphane Chazelas

7

Haklısınız - \wPCRE - perl uyumlu normal ifadelerin bir parçasıdır. Yine de 'standart' regex'in bir parçası değil. http://www.regular-expressions.info/posix.html

Bazı sürümleri sedbunu destekleyebilir ama en kolay yolu sadece kullanmaktır öneririm perliçinde sedbelirterek modunda -pbayrağı. (İle birlikte -e). (Daha fazla ayrıntı içinde perlrun)

Ancak []bu örnekte etrafına ihtiyacınız yok - bu geçerli şeyler grupları için.

echo here  | perl -pe 's/\w+/gone/'

Veya Windows'ta:

C:\>echo here  | perl -pe "s/\w+/gone/"
gone
C:\>echo here  | perl -pe "s/[\w\/]+/gone/"
gone

Daha perlrefazla PCRE olayı için bakın .

Buradan perl alabilirsiniz: http://www.activestate.com/activeperl/downloads


Lütfen benim sorum \wile [\w]arasındaki soruna dikkat edin . Hangisinin çalıştığını ve hangisinin çalışmadığını netleştirmek için her komutun çıktıları ile güncelleyeceğim. Özellikle, sedanlar \w, ama değil [\w]. Ayrıca [\w]çalışmam gerekiyor çünkü kullanmak istiyorum [\w/].
BERS

Bu durumda, muhtemelen bir alıntı problemi. Her iki şekilde de - perlyapabilir :).
Sobrique

Teşekkürler! Stéphane Chazelas'ın cevabı istediklerime biraz daha yakın (perl kurulu olmadığından - bir du * b Windows kullanıcısı, sanırım), bu yüzden cevabını kabul ettim.
BERS

Sorun değil - ama Perl'i Windows'a yüklemenizi tavsiye ederim. Bu benim başıma gelen ilk şeylerden biri ve son derece yararlı buluyorum.
Sobrique

\wPerl'de olmadan önce GNU grep'te (80'lerde) ve muhtemelen bundan önce bile GNU emac'lerinde idi.
Stéphane Chazelas

1

Ben şüpheli grepve sedne zaman uygulamak için farklı şekilde karar veriyorlar []ve ne zaman genişletmek için \w. Perl regex \w, herhangi bir kelime karakteri anlamına gelir ve []içindeki karakterlerden herhangi birini bir eşleme olarak uygulamak için bir grup tanımlar. Eğer "genişletmek" Eğer \wdaha önce []bu sözcük karakterleri hepsi bir karakter sınıfı olacak. Yerine Bunu yaparsanız []ilk iki karakterlerle bir karakter sınıfını sahip olacak \ve wböylece bir veya daha fazla bu iki karakter içeren herhangi bir desen eşleşir.

Bu yüzden görünüyor sedgörüyor []ve eşleştirilecek karakter içeren yerine özel dizisi onurlandıran olarak ele \wolarak perlve grepyapmak. Tabii ki, []bu örnekte tamamen gereksiz, ancak belki de bunun önemli olacağı durumları hayal edebiliyoruz, ama sonra onu pens ve ors ile çalışmasını sağlayabilirsiniz.


Öyle olsaydı şaşırırdım. \ bu bir kaçış kodudur ve sınırlayıcılardan kaçmak için kullanırsınız. Doğası gereği bu, başka herhangi bir şeyden daha yüksek bir önceliğe sahip olması gerektiği anlamına gelir. Bence uygulanmadığı daha muhtemel çünkü bence \wnormal ifade özelliğinin bir parçası değil
Sobrique

Eh, ampirik olarak benim için gnu sed kullanan durum gibi görünüyor: echo whe\\ere | sed -r 's/[\w]+/gone/gbana gonehegoneereher ` and biriyle uyuşuyor ve ikame yapıyormuş gibi veriyor
Eric Renouf

Eric Renouf'un ne gördüğünü onaylayabilirim. Yani bir şekilde ters eğik çizgiyi kaldırmak istiyoruz? :)
BERS

Bunun doğru cevap olduğunu sanmıyorum. Sed, farklı karakter sınıfı tanım türlerinin karıştırılmasını desteklemez, bu nedenle yanıt, her iki karakter sınıfı türünü başka bir araç seçmek için kullanmanız gerekiyorsa veya sed seçerseniz, desteklediği sözdizimini kullanıyorsanız
Eric Renouf
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.