Normal ifade karakterleri olarak yorumlanmak için neden sed'deki normal ifade karakterlerinden kaçmam gerekiyor?


11

Örneğin görünüyor
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
Bunu gerekir normal bir ifade oluşturacak şekilde karakterleri çıkarabilirsiniz. Bu durumda birkaç kez yorumlanabilmek için diş tellerinden kaçmak zorunda kaldım.
Neden? Ben kaçmadıkça her şeyin normal ifade karakteri olmasını bekliyordum. Yani tam tersi.



@DravSloan: Aynı olduğundan emin değilim. Vim'de varsayılan olarak metin ararsınız ve regex'i aramak için kaçmanız gerekir.Ancak bu durumda biçim s/regex//gzaten bir normal ifade bekler ve bunun metin olması beklenir kaçacak
Jim

Yanıtlar:


14

Bunun nedeni sedkullanımları POSIX BRES Eres aksine (Temel Düzenli İfadeler) muhtemelen Perl veya arkadaşlarından alıştığınız (Normal İfadeleri Extended).

Gönderen sed(1)adam sayfası:

REGULAR EXPRESSIONS
       POSIX.2 BREs should be supported, but they aren't completely because of
       performance problems.  The \n sequence in a regular expression  matches
       the newline character, and similarly for \a, \t, and other sequences.

Yukarıdaki bağlantıdan ilgili alıntı:

Temel Düzenli İfadeler veya BRE lezzeti, geleneksel UNIX grep komutu tarafından kullanılana benzer bir lezzeti standartlaştırır. Bu, günümüzde hala kullanılmakta olan en eski düzenli ifade aromasıdır. Bu lezzeti birbirinden ayıran şeylerden biri, çoğu meta karaktere, meta karaktere lezzet vermek için ters eğik çizgi gerektirmesidir. POSIX ERE dahil olmak üzere diğer birçok lezzet, metakarakterlerin anlamını bastırmak için ters eğik çizgi kullanır.

Alıntı alıntı Craig Sanders'ın yorumundan :

GNU sed'de en azından sed'e -r veya --regexp-genişletilmiş komut satırı seçeneğiyle genişletilmiş normal ifadeler kullanmasını söyleyebilirsiniz. Bu aşırı komut dosyası ile sed komut çirkin önlemek için yararlı olur.


1
En azından GNU sed'de sed'in -rveya regexps --regexp-extendedkomutunu veya komut satırı seçeneğiyle kullanmasını söyleyebilirsiniz . Bu aşırı komut dosyası ile sed komut çirkin önlemek için yararlı olur.
cas

@CraigSanders Bunun için teşekkürler. Cevaplamak için eklendi.
Joseph R.

@CraigSanders, diğer sed(onlar destek Eres, çoğunlukla BSD yaptığımda) uygulamaları kullanma eğiliminde -Eyerine için (bunun için aynı seçenek beri çok daha mantıklı olan grep. Neden GNU sedseçti -rbana bir sır olduğunu).
Stéphane Chazelas

evet, benim için de bir gizem. -E kullanmak daha mantıklı olacaktır. ve daha sonra GNU grep ile eşleşmesi için -F, -G ve -P ekleyin. IMO gawk aynı RE argümanlarından da faydalanacak ... ya da en azından -P.
cas

12

Bu tarihsel nedenlerden dolayı.

Regexp ilk olarak ed70'li yılların başlarında yardımcı programda Unix'te tanıtıldı . Gerçi eddayanıyordu qedgerçekleştirme aşamasında aynı yazarlar tarafından daha karmaşık Regexp'i anlaşılan, edsadece anlaşılmış ^, $, [...], ., *ve \yukarıdakilerin hepsi kaçmak için.

Şimdi, daha fazla operatöre ihtiyaç duyulduğunda, geriye dönük uyumluluğu bozmadan bunları tanıtmanın bir yolunun bulunması gerekiyordu. Bir komut dosyası kullanmak kullandıysanız s edolarak komutu s/foo() {/foo (var) {/gtüm örneklerini değiştirmek için foo() {birlikte foo(var) { ve bir tanıtılan (veya {operatörü, yani o senaryoyu kırar.

Ancak hiçbir komut dosyası yapmaz s/foo\(\) {/foo\(var\) {/, çünkü bu bir RE operatörü olmadığı s/foo() {/foo(var) {/için kaçmak için hiçbir neden yoktu (. Bu nedenle, yeni bir \(veya \{işleç eklemek, eski sözdizimini kullanarak mevcut bir komut dosyasını kırması pek olası olmadığından geriye dönük uyumluluğu bozmaz.

İşte böyle yapıldı. Daha sonra, \(...\)başlangıçta sadece s edkomut gibi s/foo\(.\)/\1bar/ve daha sonra gibi şeyler yapmak için eklendi grep '\(.\)\1'(ancak eşik gibi değil \(xx\)*).

UnixV7'de (1979, neredeyse on yıl sonra), yeni egrepve awkyardımcı programlara genişletilmiş düzenli ifade adı verilen yeni bir düzenli ifade biçimi eklendi (yeni araçlar oldukları için, kırılacak geriye dönük uyumluluk yoktur). Sonunda, bu Ken Thompson'un antik mevcut işlevselliği ile sağlanan qed(münavebe operatörü |gruplama, (..)*) ve benzeri birkaç operatörleri eklendi +ve ?(ama temel düzenli ifadeler backref özelliği yoktu).

Daha sonra BSD'ler eklendi \<ve \>(hem BRE hem de ERE'ye ) ve SysV eklendi \{ve \}sadece BRE'lere.

Böyle bir geriye dönük uyumluluk kırılarak ERE'ye kadar geç değildir {ve }ERE'ye eklenmiştir. Herkes eklemedi. Örneğin, awk4.0.0 (2011) sürümüne kadar GNU {, POSIX uyumluluk moduna zorlanmadığı sürece desteklemedi .

GNU grep90'lı yılların başında yazıldığında, hem BSD hem de SysV'den (örneğin \<, {) tüm güzellikleri ekledi ve BRE ve ERE için iki ayrı regexp sözdizimi ve motora sahip olmak yerine, aynı operatörleri sadece BRE meslektaşlarına uyguladı. (, ?, {, +bir eğik çizgi ile öncesinde gerekir (başka bir BRE uygulamaları ile uyumlu olması gerekir). Bu yapabileceğin yüzden .\+GNU içinde grep(yani POSIX değil ya da diğer uygulamaları tarafından desteklenen rağmen) ve yapabileceğiniz (.)\1GNU içinde egrep(yani POSIX değil veya GNU gibi diğer birçok uygulamaları tarafından desteklenen gerçi awk).

Ekleme \xoperatörleri geriye doğru uyumlu bir şekilde daha operatörleri eklemek için tek yol değildir. Örneğin, perlkullanılmış (?...). Bu, ERE'lerde (?=...)geçerli olmadığı için ERE'lerle geriye dönük olarak uyumludur .*?. vimbenzer operatörler için bunu tanıtarak \@=veya .\{-}örneğin farklı şekilde yaptılar.

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.