Normal ifade ne zaman Normal İfade değildir?


9

Resmi diller kolej dersim için çalıştığım için, normal ifadeyi kullanarak asal bir sayının nasıl bulunacağını açıklayan bu büyüleyici yazılara ( Bir İki ) rastladım . Dediğim gibi, bir regexp'in değil, bir normal ifade . Normal bir ifade, bir Sonlu Durum Otomatik Verileri tarafından hesaplanan dizelerle eşleşebildiğinden ve asal sayı bulmak bir FSA tarafından yapılamadığından, blog gönderisinde gösterilen normal ifade, dizeyle eşleşmek için geriye doğru izleme yaptığı için tamamen normal bir ifade değildir .

Asla herhangi bir normal ifade kullanmadım, şimdi sorum:

Bir regexp'i "gerçek" normal ifadeden sadece ona bakarak nasıl anında tanıyabilirim?

Tanımlar: Düzenli ifade ile biçimsel dillerde tanımlanmış olan kavramdan söz ediyorum. Normal ifade ile, modern programlama dillerinin desteklediği kavramı kastediyorum; regexp sözdizimi genellikle backreferences gibi ek özellikler içerir. Programlama dillerinde görülen regexps, resmi diller stili düzenli ifadelerden kesinlikle daha güçlüdür .


5
Normal ifade sadece düzenli ifadenin kısaltmasıdır. Asal sayılar hesaplaması, normal ifadelere değil, bir Perl saldırısına dayanır.

1
Oldukça basit. Düzenli diller birleştirme, tekrarlama ve değişim kullanır. Bir motor bunlara eşdeğer olmayan bir şeyi desteklediğinde, normal değildir.
Kilian Foth

1
İlgili sorular: 1 , 2 , 3 .
Raphael

@Yannis Çitin üzerinden CS'ye atlarsanız, bu artık doğru değil. Programlama dillerinde görüldüğü gibi normal ifadeler (resmi diller stili) normal ifadelerden kesinlikle daha güçlüdür ve kısa biçim "normal ifade" kural gereğidir (bir tanesinin ne kadar yaygın olduğunu bilmiyorum), ikincisi için değil tür.
Raphael

@KilianFoth Bu gerçekten yararlı bir açıklama değil. Örneğin, güçlerini artırmadan normal ifadelere olumsuzluk (veya gerçekten de herhangi bir sonlu Boolean bağlayıcı seti) ekleyebilirsiniz.
David Richerby

Yanıtlar:


13

tl; dr geri teper.

Bir orada en kısa zamanda gibi \1bir normal ifade değil regexp içinde (unicode kaçmak için kullanılmaz ya da herhangi bir sayı).

Backrefs herhangi bir n> 1 için n ve ardından b ve n ile eşleşen (a+)b\1maçları eşleştirmenizi sağlar . Bu normal bir dil değil (normal olmayan bir dilin poster çocuğu).aa

Backref'in keyfi olarak uzun bir dizeyle eşleşen regexp içeren bir gruba başvurması veya bir *veya içermesi neredeyse yeterlidir +. (A)B\1A'nın sonlu bir dil olduğu formun düzenli ifadesinin tek istisnası ( bunları kabul eden tüm kelimelerin numaralandırılması ile değiştirilebilir). word1+Bword1|word2+Bword2A'ya vb. Dönüştürebilirsiniz çünkü A sonludur.

Etraftaki gruplar normal ifadenin düzenliliğini kaldırmaz. A(?=B)Cregexes kesitidir AB.*ve ACve 2 normal dillerin kesiti düzenlidir. Negatif ilerleme, B.*tamamlayıcısı (normal dillerin tamamlayıcısı düzenli) kullanılması dışında benzerdir . Geriye İlerleme de tam olarak aynı A(?<=B)Cenine kesitidir ACve .*BC.


Bu gerekli ve yeterli mi? Bana (a)\1bir backref kullanırken, aabu yüzden düzenli olarak eşdeğer ve bu nedenle önemsiz gibi görünüyor . Ayrıca ileriye dönük iddiaların Düzenli olmayan dilleri tanımak için kullanıp kullanamayacağını merak ediyorum.
MSalters

1
@ MSalters: Gerçekten teknik olmak istiyorsanız, (a)\1normal bir ifade değil, normal bir dili tanır.
Jörg W Mittag
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.