Tarihi bakış açısı
Wikipedia makalesi , düzenli ifadelerin kökenleri hakkında oldukça ayrıntılıdır (Kleene, 1956). Orijinal sözdizimi sadece nispeten basitti *
, +
, ?
, |
ve gruplama (...)
. Özlü ( ve okunabilir, ikisi mutlaka karşı çıkmaz), çünkü biçimsel diller özlü matematiksel notasyonlarla ifade edilme eğilimindedir.
Daha sonra, sözdizimi ve yetenekler editörlerle birlikte gelişti ve tasarımdan etkilenmeye çalışan Perl ile büyüdü ( "ortak yapılar kısa olmalı" ). Bu, sözdizimini çok karmaşıklaştırdı, ancak insanların artık normal ifadelere alıştıklarını ve (eğer okumazsa) yazmada iyi olduklarını unutmayın. Bazen yalnızca yazma olmaları, çok uzun olduklarında genellikle doğru araç olmadıklarını göstermektedir.
Normal ifadeler kötüye kullanıldığında okunamaz olma eğilimindedir.
Dize tabanlı normal ifadelerin ötesinde
Alternatif sözdizimleri hakkında konuşalım, şu an var olan şeye bir bakalım ( cl-ppcre , Common Lisp ). Uzun düzenli ifadeniz aşağıdaki gibi ayrıştırılabilir ppcre:parse-string
:
(let ((*print-case* :downcase)
(*print-right-margin* 50))
(pprint
(ppcre:parse-string "^(?:([A-Za-z]+):)?(\\/{0,3})(0-9.\\-A-Za-z]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$")))
... ve aşağıdaki biçimde sonuçlanır:
(:sequence :start-anchor
(:greedy-repetition 0 1
(:group
(:sequence
(:register
(:greedy-repetition 1 nil
(:char-class (:range #\A #\Z)
(:range #\a #\z))))
#\:)))
(:register (:greedy-repetition 0 3 #\/))
(:register
(:sequence "0-9" :everything "-A-Za-z"
(:greedy-repetition 1 nil #\])))
(:greedy-repetition 0 1
(:group
(:sequence #\:
(:register
(:greedy-repetition 1 nil :digit-class)))))
(:greedy-repetition 0 1
(:group
(:sequence #\/
(:register
(:greedy-repetition 0 nil
(:inverted-char-class #\? #\#))))))
(:greedy-repetition 0 1
(:group
(:sequence #\?
(:register
(:greedy-repetition 0 nil
(:inverted-char-class #\#))))))
(:greedy-repetition 0 1
(:group
(:sequence #\#
(:register
(:greedy-repetition 0 nil :everything)))))
:end-anchor)
Bu sözdizimi daha ayrıntılıdır ve aşağıdaki yorumlara bakarsanız, mutlaka daha okunaklı olması gerekmez. Bu nedenle, daha az kompakt bir sözdiziminiz olduğundan, işlerin otomatik olarak daha net olacağını varsaymayın .
Bununla birlikte, normal ifadelerinizde sorun yaşamaya başlarsanız, bunları bu formata dönüştürmek kodunuzun şifresini çözmenize ve hata ayıklamanıza yardımcı olabilir. Bu, tek karakterli bir hatanın tespit edilmesinin zor olabileceği string tabanlı formatlara göre bir avantajdır.
Bu söz diziminin en büyük avantajı , dizge tabanlı bir kodlama yerine yapısal bir format kullanarak normal ifadeleri değiştirmektir. Bu, programınızdaki diğer veri yapıları gibi ifadeleri oluşturmanıza ve oluşturmanıza olanak sağlar . Yukarıdaki sözdizimini kullandığımda, bunun nedeni genellikle daha küçük parçalardan ifadeler oluşturmak istediğimdir (ayrıca bkz . CodeGolf cevabım ). Örneğin, 1 yazabiliriz :
`(:sequence
:start-anchor
,(protocol)
,(slashes)
,(domain)
,(top-level-domain) ... )
Dizi tabanlı düzenli ifadeler, dizi birleştirmeyi ve yardımcı fonksiyonlara sarılmış enterpolasyonu kullanarak da oluşturulabilir. Ancak eğilimi dize manipülasyonlar ile sınırlamalar vardır yığılmayı kodu (değil ters tırnakların aksine vs yuvalama sorunları düşünmek $(...)
bash; ayrıca, karakterlerin baş ağrısı verebilir kaçış).
Ayrıca yukarıdaki formun (:regex "string")
formlara izin verdiğine dikkat edin, böylece veciz notasyonlarını ağaçlarla karıştırabilirsiniz. Tüm bunlar IMHO'ya iyi okunabilirlik ve beste kabiliyetine yol açmaktadır; delnan tarafından dolaylı olarak ifade edilen üç sorunu ele almaktadır (yani, düzenli ifadelerin dilinde değildir).
Sonuçlandırmak
Çoğu amaç için, kısa nota aslında okunabilir. Geriye dönük izlemeyi içeren genişletilmiş notasyonlarla uğraşırken zorluklar var, ancak bunların kullanımı nadiren haklı. Düzenli ifadelerin haksız kullanımı, okunamayan ifadelere yol açabilir.
Normal ifadelerin dizge olarak kodlanması gerekmez. Düzenli ifadeler oluşturmanıza ve oluşturmanıza yardımcı olacak bir kitaplığınız veya aracınız varsa, dize işlemleriyle ilgili birçok olası hatadan kaçınırsınız .
Alternatif olarak, biçimsel gramerler daha okunaklıdır ve alt ifadeleri adlandırma ve özetlemede daha iyidir. Terminaller genellikle basit düzenli ifadeler olarak ifade edilir.
1. İfadelerinizi okuma zamanında oluşturmayı tercih edebilirsiniz, çünkü normal ifadeler bir uygulamada sabit olma eğilimindedir. Bakınız create-scanner
ve load-time-value
:
'(:sequence :start-anchor #.(protocol) #.(slashes) ... )