Normal İfadeleri nasıl öğrenirsiniz? [kapalı]


80

Nereden öğreneceğimi sormuyorum . Çevrimiçi ortamda çok sayıda iyi kaynak buldum ve kitap vb

Ama ben onları nasıl hallediyorum? Bunun başlangıcı, sonu nerede? Regexp işlemci ne zaman metin üzerinde ilerliyor, ne zaman durur ve başka bir eşlemeyi dener? vb.

Mısır piramitleri üzerindeki hiyeroglifleri çözmeye çalışmak gibi hissediyorum.


2
Konuyla ilgili sıralama - regular-expressions.info . Bunu ve @ Jalayn'in önerisini aşağıda kullanın. Yaparak öğrenmek!
Freiheit

6
gskinner.com/RegExr , bulduğum regex'leri geliştirmek için en iyi araçtır.
Callum Rogers

Her seferinde biraz. Basit şeyler ("aaa", "aa.", "A * b", vb.) İle başlayın ve uygulamaya özel bileşenlere (yani PCRE) kadar yükselin. Sonra bir desen ile gelip ona uygun bir regex yapmaya çalışın.
tylerl

RegexBuddy'nin müthiş programında deneme yanılma ile öğrendim. regexbuddy.com (Bu reklam için kredi alamadım, bu program gerçekten öğrenmeyi kolaylaştırdı)
Yam Marcovic 23:11

rubular.com , regex'ler geliştirmek için iyi bir araçtır.
Gazler

Yanıtlar:


68

Otomata teorisi bilgisinin anlayış için kritik olduğunu düşünüyorum .

Bir otomatın ne olduğunu ve normal dillerin nasıl tanımlandığını anladığınızda, düzenli ifadeleri anlamak çok daha kolay olacaktır.

Belirli bir sözdizimine ve çeşitli uygulamalar arasındaki farklara gelince ... Şey, sadece hatırlamanız gereken bazı şeyler. Bunun için de yardımlar var .

Düzenle

Aşağıdaki yorumlardan bazıları önemli noktaları ortaya çıkardı:

  1. Düzenli ifadelerin (çoğu programlama dilinde uygulandığı gibi), otomat teorisindeki normal ifadelerin bir üst kümesi olduğunu unutmayın. İyi bir teorik arka plan başlamak için yararlı bir yer olsa da, size her şeyi anlatmaz. (Teşekkürler, David Thornley)

  2. Çok sayıda yorumcu, çeşitli regex sözdizimini teorik temeli öğrenmeden öğrenmenin mümkün olduğunu söylüyor. Nasıl çalıştığını tam olarak anlamadan sözdizimini öğrenebileceğiniz doğru olsa da, tam anlayışın OP'nin peşindeydi olduğu izlenimini edindim. Asıl soru şuydu: işlemci ne zaman ilerliyor? Ne zaman bitiyor? Bunun bir eşleşme olduğuna nasıl karar verir? Temel, teori ve Otomata Teorisi'ne dayanıyor. Elbette, motorun nasıl çalıştığını bilmeden bir araba sürebilirsiniz. Fakat eğer “gaz aslında onu nasıl tahrik eder” sorulursa - motorun nasıl yapıldığı hakkında konuşmanız gerekir , değil mi?


Yorum yapanlar: Bu sorunun daha ince noktalarını tartışmak istiyorsanız, lütfen sohbeti kullanın . Aksi takdirde, lütfen bir cevap bırakmayı veya en doğru bulduğunuz cevapları oylamayı düşünün.

Düzenleme için teşekkürler. Bu, bu cevabı gerçeğe çok daha yakın hale getirir. Hala Otomata Teorisi'ni bilmeniz gerektiğini düşünmeme rağmen (bilmiyorum ama yine de karmaşık düzenli ifadeler yazabiliyorum), teoriyle ilgili bazı bilgilerin yardımcı olabileceği konusunda hemfikirim. Özellikle geri izlemenin nasıl yürüdüğünü ve açgözlü / ungreedy / iyelik ölçütleri tarafından kontrol edildiğini bilmek gerçekten anlamanıza yardımcı olabilir.
NikiC

Sadece 2 kuruşum: MSDN'nin Kanal 9'unda C ++ STL regex kütüphanesi ile ilgili yeni bir video dizisinde, aynı zamanda STL'nin sağlayıcısı olan sunucu, onu bir otomata olarak uyguladıklarını söyledi. Öyleyse bu teoriyi bilmek OP'ye gerçekten regex'in nasıl çalıştığı hakkında bazı görüşler vermelidir.
korbes

5
Açılış konuşmasına hiç katılmıyorum. Düzenli ifadeler öğrendiğimde otomat teorisi hakkında hiçbir şey bilmiyordum. Otuz yıl sonra hala bilmiyorum. Bildiğim şey, bir man sayfasını nasıl okuyacağımı, tam anlamıyla okuyacağımı ve bilgi isteminde nasıl deney yapacağımıydı.
Bryan Oakley

1
@Bryan iyi ... Deneyiminiz türünü kanıtlıyor. Belki nasıl kullanılacağını biliyorsun, ama nasıl çalıştığını gerçekten anlamıyorsun . Yaparsan - o zaman otomata teorisi hakkında bir şeyler biliyorsun, ismini bilmesen bile. Ancak, otomata teorisini bilmeden düzenli ifadeleri tam olarak anlayamazsınız ve man sayfalarını okumak konusunda hiçbir şey size yardımcı olamaz (tabii ki otomata teorisini açıklayan man sayfalarını okumadığınız sürece).
littleadv

36

Pratik yaparak.

Web kazıma ile eğlenerek öğrendim. Eminim bunu sadece eğlence için yapmıyordum.

Bir örnek: En son futbolu, teninizi (aslında beğendiğiniz sporu) en sevdiğiniz spor web sitesinden aldığınız bazı kodları yazın. Sayfayı yüklemek, puanları düzenli ifadelerle çıkarmak ve konsola veya bazı metin dosyalarına çıkarmak için bazı kodlar yazarak yapın. Seçtiğiniz normal ifadeyle yalnızca puanları aldığınızdan ve başka hiçbir şey almadığınızdan emin olun. Bazen bu oldukça zor olabilir :-)

İkinci örnek: En sevdiğiniz web kamerasının resmini alan bir kod yazın (örneğin Sinfest'i çok seviyorum ) ve bu dosyayı sabit diskinizde bir yerde saklar. "İmg" etiketini ve içeriğini almak için sadece normal ifadeleri kullanın. İsteğe bağlı olarak, bir yere kaydedilmişse başlığını da alın.


15
HTML'yi normal ifadelerle ayrıştırmak genellikle kötü bir fikirdir.
Saat

10
Tabii ki kötü bir fikir. DOM / Sax ayrıştırıcılarını veya diğer özel XML okuyucularını kullanmak "genel olarak" kullanılması gereken şeydir. Ancak buradaki konu, düzenli ifadeler öğrenmekle ilgilidir ve normal ifadeler hakkında öğrendiklerimi "eğlenceli" bir şekilde düşündüğümü paylaştım.
Jalayn

3
HTML web sayfaları için XML ayrıştırıcıları kullanmak, onları düzenli ifadelerle kazımaktan çok daha kötü bir fikirdir.
skolima

8
Ah, bu konuda ne düşündüğüm konusunda daha kesin olmak istedim ama tembeldim ve yorumuma sadece tepki verdim ... Sanırım hepimiz, tüm belgeyi ayrıştırmak için düzenli ifadeler kullanmanın kötü bir fikir olduğunu kabul edebiliriz. 2. HTML'yi ayrıştırmak için XML ayrıştırıcıları kullanmak kötü bir fikirdir 3. XHTML'yi ayrıştırmak için XML ayrıştırıcıları kullanmak doğru 4. Bir-astarları almak için normal ifadeleri kullanmak veya HTML'den çok özel bir bilgi doğrudur. Ya da sadece özetleyebilirim: doğru iş için doğru araç ...
Jalayn 23:11

23

Kaynak sormadığını biliyorum ama Jeffrey EF Friedl'in Düzenli İfadeleri Mastering , nasıl çalıştıklarını ve nasıl kullanıldıklarını öğrendi. Farklı şeyleri ayrıştırmak için birçoğunu kullanma noktasına geldikten sonra bile, ilk bölümde benim için yeni şeyler vardı.

O lanet regexp'i anlamak ister misin? Bu kitabı oku.


2
Bu kesin cevap olmalı.
İnce,

1
+100,000 Şimdiye kadarki en iyi teknik kitaplardan biri ve konuyla ilgili olarak.
Affe

Bu kitabı çok sevdim. Kilit nokta, Regex'te bulunan tüm farklı işlevleri anlamamda bana yardımcı oldu. Bir kitap okumaktan tüm sözdizimini ezberleyemezsiniz, ancak kitap size var olan her şeyi gösterir, böylece bir problemi çözdüğünüzde hangi araçları çözmeniz gerektiğini bilirsiniz.
Kibbee

Kesinlikle bu cevap için +1. Nihayet oturdum ve bu temel hacmi satır satır okuyana kadar regex'e fırlattım. Friedl bana bugün bizi rahatsız eden standart dışı varyasyonların hepsine katlanabileceğim bir vakıf verdi! Bu referansı OP ve herkese tavsiye ederim. Ayrıca +1, yorumu için de!
John Tobler

19

Bunun başlangıcı, sonu nerede? Regexp işlemci ne zaman metin üzerinde ilerliyor, ne zaman durur ve başka bir eşlemeyi dener? vb.

Ben başlamak istiyorum hedeflerinizi netleştirmek ve daha sonra öğrenme stilini endam .

Sorunuzla ilgili beni etkileyen şey, "düzenli ifadeleri nasıl öğrenirim?" Diye sormanızdır. ve sonra hemen "normal ifade motoru dahili olarak nasıl çalışır?" sorusu ile devam eder. Bu iki şeyin birbiriyle bir ilgisi olduğunu ima ediyor gibisiniz, ki bu bir söylem noktası. Belki bir şeyin nasıl parçalandığını veya kendiniz inşa ederek nasıl çalıştığını öğrenen bir insansınız.

Yeni başlayan uygulamalar için, genellikle bir aletin etkili bir şekilde kullanılması için nasıl çalıştığını anlamaya gerek yoktur. Tahta delikler açmak için bir matkap motorunun nasıl çalıştığını bilmenize gerek yoktur; Eğer nasıl anlamamız gerekir kullanmak matkap, değil nasıl inşa matkap.

Peki amacın nedir? Normal bir ifade motorunun nasıl oluşturulacağını mı öğrenmek istiyorsunuz ? veya işle ilgili sorunları çözmek için normal ifadeleri etkili bir şekilde kullanmayı öğrenmek mi istiyorsunuz ? Bu farklı hedeflere ulaşmak, muhtemelen farklı öğrenme teknikleri gerektirir.

Normal ifade motorunun nasıl çalıştığıyla ilgili sorunuza cevap vermek için: Düzenli ifadelere "klasik" teorik yaklaşım, normal ifadeyi, belirli olmayan bir sonlu otomat için bir plan olarak kullanmak, daha sonra eşdeğer deterministik sonlu otomatı oluşturmak ve sonra o otomatı girdiye karşı yürütmektir.

Neredeyse hiç kimse bunu birkaç nedenden ötürü yapmaz . İlk olarak, muhtemel giriş karakterlerinin sayısı ile çarpılan durumların sayısı, küçük normal ifadeler için bile çok büyük olan durum geçiş tablosunu verir. Elbette, bunların çoğu sıkıştırılabilir, ama yine de çok fazla geçiş kuralları var. İkincisi, diğer yaklaşımlar genellikle daha hızlıdır. Üçüncüsü, sözde "normal" ifadeler, modern regexp kütüphanelerindedir; Bunlar hiçbir zaman normal dil değiller ; sonlu otomata dilleri tarafından değil, genellikle push-automata tarafından tanınmaktadır.

(Tüm bunların nasıl çalıştığı hakkında uzun bir dizi yazmaya başladım, ancak yalnızca ilk on iki makaleden sonra buharım bitmişti.

Gerçek düzenli ifade motorları bunun yerine tipik olarak bir geri izleme stratejisi kullanır. JScript motoru için on yıl önce oluşturduğumuz normal ifade motoru, şimdi normal ifadeyi, dizileri tanımak ve önceki durumlara geri dönmek için ilkelleri içeren bir bytecode dilinde derler. Daha sonra bu bytecode dili için bir tercüman yaptık.

Düzenli ifadelerin nasıl kullanılacağına dair oldukça sağlam bir anlayışa sahip olmadan önce bir regexp motorunun nasıl çalıştığını anlamaya çalışmam . Optimizasyon stratejilerine girmeden önce çeşitli motorları kullanmaya odaklanın.


+1 çünkü regex'leri kullanırken bilmeniz gereken birçok şeyi ele alıyorsunuz; Bununla birlikte, içerdeki bilgileri bilmek gerekmediğine karar vermenize katılmıyorum. Sondaj için tamamen haklısın; bilgisayarlarda, ilk bakışta düşündüğümden kısa bir süre önce, uygulamasında ustalaşmak için bir şeyin içini anlamak zorunda olduğum bir noktaya geldiğimi öğrendim - C ++ (derleyiciler), web sunucuları (HTTP) veya regex'ler (otomata teorisi). . Uzman olduğum noktaya değil, temel prensiplerin iyi anlaşılması genellikle öğrenmenin en hızlı yoludur.
Felix Dombek 22:11

3
@Felix: Bence gerçekten aynı fikirdeyiz. Ben söyledi acemi uygulamalar için orada genellikle bir araç olarak kullanmak için nasıl çalıştığını anlamak gerek. Bu çakal sözleri kasıtlı idi. İçin kalfalık veya ustaca o aracı kötü performansa sahip olacak nereye doğru tahmin böylece kendi donanımları hakkında en az şey anlamak çok yararlı olan bir aletin kullanılmasıyla, derler.
Eric Lippert 22:11

Hmm, bir şekilde katılmıyorum. Yaptığım en faydalı işletme programlarından bazıları, Lexx'te öğrendiğim teoriyi ve sorunları verimli bir şekilde çözmek için kullandılar. Haklısın, tam, doktora düzeyinde bir anlayış gerekli değildir. Blog yazılarını okumak zorunda kalacağım, en ilginç görünüyorlar.
Spencer Rathbun

Düzenli ifadelerin normal olmadığını söylüyorsunuz - ancak isimdeki dünyanın düzenli olarak eşleştiği ifadelere atıfta bulunduğunu düşündüm - örneğin, "[0-9]{3}"herhangi bir üç basamaklı sayı ile eşleşebilen normal ifade ve üç basamaklı sayı 480, normal bir örnek ifadeleri eşleşti.
konfigüratör,

1
@configurator: "Normal" bir dil, tanımı gereği, sınırlı bir otomat tarafından tanınabilen bir dildir. Her normal dil, yalnızca sendikalar, alternatifler, katiller ve Kleene Star'dan oluşan "düzenli ifade" ile tanımlanabilir. Ancak bugünlerde "normal ifade" motorlarının çoğu, normal dillerden daha karmaşık dilleri tanımaktadır; örneğin, "doğru şekilde parantez içinde parantez bulunan cümleler" dili düzenli değildir, ancak bazı regexp motorlarında onu "normal ifade" ile eşleştirebilirsiniz.
Eric Lippert

6

Onlarla nasıl başa çıkarım?

Herhangi bir yeni şey gibi:

10 Study
20 Practice
30 goto 10

Ders çalışma

En başarılı öğretmenlerin herhangi bir konuyu öğretmeye başladığını ilk önce konuyla ilgili biraz arka plan sağlayarak buluyorum. Ne öğrendiğinize ve en önemlisi neden öğrendiğinize ilişkin bir bağlamın olması önemlidir .

Her şey dize eşleşiyor

Normal İfadeler, metindeki eşleşen desenlerin bir yoludur. Pek çok başka programlama diline dahil edilmiş bir bildirim dilidir.

Bilgilendirici bir dil olduğunu vurgulamak isterim, düzenli ifadeler hangi dizginin eşleşeceğini ifade etmek için yararlıdır , ancak programın eşleşmeyi nasıl yapacağını hiçbir şekilde ifade etmezler . Bu sebeple, aynı programlama dilinde normal ifadeleri çok hızlı ve çok yavaş kullanmak, sadece farklı bir RegEx ayrıştırıcı kullanarak mümkündür.

Düzenli ifadeler oluşturmanın nedeni çoğu programlama dilinin oluşturulması için aynıdır: programcılar kendilerini aynı karmaşık işi tekrar tekrar gerçekleştirirken bulmuş ve kodu daha basit bir şekilde yazmak istediklerine karar vermişlerdir.

Bazıları, önceki cümlenin çizgileri boyunca bir şeyler söyleyerek şikayet eder (ve etmelidir):

RegEx bir programı daha basit hale getirmiyor.

bu doğru

RegEx bir programı daha basit yapmaz , RegEx programı yazmayı daha basit hale getirir . Tüm doğru vakaların doğru şekilde eşleştiğinden ve yanlış durumların tamamının bulunmadığından emin olmak için testinizde hala kapsamlı olmanız gerekir. "Tümünü" test etmek gerçekten zor ve karmaşık modellerle "çoğu" yu test etmek gerçekten zor. En kötüsü, hala "bazı" vakaları test ediyor olmalısınız.

bazı örnekleri bir araya getirip, JavaScript'in RegEx motorunu zorunlu olarak seçtim çünkü tarayıcıda kolayca test edebiliyorum ve RegEx değişmezlerini kullanırken kaçan herhangi bir dize yapmak zorunda kalmayacağım.

Normal dize eşleştirmesi yaptığınızda, bir dize değerini diğerine karşı sınarsınız. Herhangi bir yerden gelebilirler, ancak sonunda birbirleriyle karşılaştırılan iki tel alır:

if ( 'foo' == 'bar' ) doSomething();

Bu örnek berbat çünkü hiçbir şey yapmaz

if ( foo == 'bar' ) doSomething();

Çok daha iyi; Şimdi, aslında bir şeyin yapılıp yapılmayacağını önceden bilmiyoruz. Artık kullanıcı girişi kabul etmeye başlayabiliriz:

if ( prompt( 'Say "bar" to do something.' ) == 'bar' ) doSomething();

Harika, şimdi kullanıcılar giriş yapabilir barve bir şeyler olabilir, sizden "bar"bunun işe yaramadığını ya da "BAR" çalışmadığını veya BRA100 kez yazdıklarını ve hiçbir şey olmadıklarını söyleyen hata raporlarını alana kadar gerçekleşir.

Yanlış yazımları ve fazladan karakterleri dikkate almamak 'bar' != 'BAR've programcıların, karakterlerin yanlış olduğu durumlarda sınanmanın bir yolunu düşünmeleri gerekir.

Basit çözüm, kullanım toLowerCase. Bu harika çalışıyor, fakat eşleştirirken Amerikan İngilizcesi üzerinden İngiliz İngilizcesi kullanan kullanıcılarımız ne durumda something == 'color'? Şimdi eşleşmen gerekecek something == 'color' || somthing == 'colour'.

Uzun lafın kısası, basit desenler çok hızlı bir şekilde tekrarlayan kodlara dönüşür.

Renk örneği basitçe şununla eşleştirilebilir:

/colou?r/.test( something )

Düzenli ifadelerin temellerinin sağlam bir şekilde anlaşılması, tekerleği yeniden icat ederek harcadığınız zamanı önemli ölçüde azaltabilir.

Nerede çalışmalı?

Düzenli ifadeler uygulayan çoğu dil, bu dilde Normal ifadeler kullanmanın belirli bir sözdizimi için mevcut en az bir kaynağa sahiptir. One JavaScript MDN'yi bulunabilir

oku onu.
hepsini.
sonra tekrar oku.

Öğrenmesi zaman alır, bunu bir yatırım olarak düşünün: RegEx'i öğrenmek için bir saat, bir dizi dizgi eşleştirmesi yapmanız gerektiğinde bir saat, daha sonra bir sonraki saatte bir saat tasarruf sağlar.

Uygulama

RegEx ile ilgili her şeyi okuduktan sonra, muhtemelen çoğunu anlamayacaksınız. Çünkü aslında onunla hiçbir şey yapmıyorsun .

Neden bu örnek için JS'yi seçtiğimi söyledim, tarayıcınızda bununla uğraşmanızı tavsiye ediyorum. Hızlıdır ve bunu doğrudan URL çubuğunuzda yapabilirsiniz.

JS'nin RegEx'i kullanmanın birkaç farklı ve basit yolu vardır:

string.match( regex )
regex.exec( string )
regex.test( string )

Gibi basit bir şeyle başlayarak:

javascript:'color'.match(/colou?r/);

Ayağınızı kapıya almanın kolay bir yoludur. Oynayın, neyin eşleştiğini ve neyin eşleşmediğini görün.

Uygulamaya takıldığınızda, devam edin 30. Daha fazlasını öğrenmek için okumanız gerekir, ancak öğrendiklerinizi gerçekten anlamak için pratik yapmanız gerekir.


Tarayıcıda JavaScript ile mesajlaşmayı önermek için +1.
John Tobler

5

Brian Kernighan, Beautiful Code kitabında basit bir eski işlemci yazar . Kaynakları aradığınızı fark ediyorum, ancak içeride temel bir uygulamanın görülmesine yardımcı olabilir .


Bahsedilen "regex işlemci" aslında disjeksiyonları uygulamamaktadır ve verilen yaklaşımla, bunları eklemek çok zordur. Kitabı beğendim ama bu hayal kırıklığına uğradığım bir şey.
Felix Dombek 22:11

4

Normal gelişimde, hata ayıklama kodu çok faydalı bilgiler sağlayabilir. Normal ifadeler farklı değildir. Yani, bir reklam gibi görünme riski altında, RegexBuddy olsun . İfadenizi ve giriş dizesini işlerken motorun ne yaptığını görsel olarak görüntülemek için harika bir aracı var.


1
+1, "Regex Hero" da çok hoş: regexhero.net/tester
Angelo

Regexbuddy en sevdiğim araçlardan biri. Ağaç görüntüsünü görmek, regex'inizi oluştururken anında test edebilmeniz gibi inanılmaz derecede faydalıdır. Sadece onu kullanarak öğrenmeye çalışmadan çok daha fazla regex öğrendim.
Chao

1
RegexBuddy'i her zaman ilginç buldum, ancak satın almak zorunda kalmaktan hoşlanmıyorum. Temel regex testi için başka birçok yardımcı program vardır. Daha az araç olmasına rağmen, regex'in yazılı bir tanımını görmek için. Regex Hero'nun ücretli versiyonu da öyle. RegexBuddy için oldukça benzersiz olan bir şey, bir karakterin her kabulünü veya reddini gösteren Regex Debugger ve her biri büyük ve çok karmaşık bir regex'i ayıklarken gerçekten yardımcı olabilecek sıra dışı ayrıntılarla geriye dönüş. Bunu yapan başka bir araç fark etmedim.
Kevin Cathcart

3

Düzenli ifadeler çok hızlı bir şekilde çok karmaşık olabilir, bu yüzden öğreticiler kullanarak öğrenmeye başlamanızı tavsiye ederim. Düzenli ifadenin en basit biçiminin, aradığınızı temsil eden bir dize olduğunu bilin. Maalesef, özel arama kurallarını tanımlayabilmek için belirli karakterler gerekir ve bu karakterlerden kaçmanız gerekir, aksi takdirde geçersiz veya yanlış bir düzenli ifade oluşturabilirsiniz.

Tavsiyem, aradığınız bir şeye bir örnek ile başlamak ve kaçmak. Başka bir deyişle, parantez içinde bir şey arıyorsanız, aradığınız metinde bu tür bir diziden bir örnek alın: (this is an example of something you'd want to find)

Değişken karakteri aramak için karakterlerden kaçış yaparak başlayın: \(this is an example of something you'd want to find\)

Sınayın, örneğinizi doğru bulduğunu doğrulayın. Ardından, yalnızca bulduğunuz örneği değil, bu tür metni bulmak için ifadeyi genelleştirin. Böylece şöyle olur: \([^)]*\) (0 dahil olmak üzere herhangi bir sayıdaki oluşum için ")" olmayan herhangi bir karakter anlamına gelir).

Tekrar test edin ve yalnızca örneğinizi bulmadığını, başkalarını da beğendiğini doğrulayın. İnternette daha karmaşık ancak daha sık düzenli ifadeler arayın ve her bir olasılık hakkında endişelenmek zorunda kalmamak için bunları mevcut düzenli ifadelerinizle düzeltin.

Bu konuda. Ve oh, öğren ve sev. \ Q ... \ E. Normal ifade dillerinin çoğunda, \ Q, değişmez bir kalıbın başlangıcını belirtir ve \ E, özellikle karmaşık kalıpları aramakla uğraşmanız ve onlardan nasıl kaçılacağınızı bilmemeniz durumunda sonunu işaretler. Bu hayatımı birkaç olaydan daha fazla kurtardı.


3

Sana basit bir soru için basit bir cevap vereceğim. Öncelikle, Düzenli İfadelerin (RegEx) ne olduğunu - ne yaptıklarını, ne işe yaradıklarını anlamanız gerekir. Sonra başlamak için harika bir araç.

  1. Bu ne? RegEx, desen eşleşmesini ifade eden bir dildir. Başka bir deyişle, onu kullanarak, metindeki kalıpları tanıyan veya bulan karakterleri bir arada oluşturabilirsiniz. Bu nasıl faydalıdır? Programlamada, bilgisayarlara bir kaynaktan (bir kullanıcı girişi, bir web sayfası vb.) Gelen metni eşleştirmelerini ve içinde belirli metin başlıklarının bulunup bulunmadığını tespit edebilirsiniz. Örneğin, bir nokta (.) Herhangi bir karakteri temsil eder - harf veya sayı. Parantez içindeki sayılar, yinelemelerin sayısını temsil eder; bu nedenle, ". {1,30}", 1 ile 30 kez tekrarlanan herhangi bir karakteri belirtir; başka bir deyişle, boş bir dize kullanamazsınız ve 30'dan daha uzun olamaz karakter. Ve oradan devam ediyor.

  2. Öğrenmeye nasıl başlanır? Gördüğüm en iyi en iyi araç Expresso , ancak yalnızca Windows içindir. İfadenize eklemek istediğiniz öğeleri tıklattığınız çok kapsamlı bir GUI'ye, ardından sonuçları görmek için çeşitli girdilere karşı kontrol etmek için bir test cihazına sahiptir. Mac'te iyi bir şey görmedim (ancak Windows’u VMWare’de çalıştırıyorum, bu yüzden gerçekten bir Mac sürümüne gerek yok), Linux’a bakmak için çok fazla zaman harcamamıştım.


1
Expresso hakkında bahşiş için teşekkürler. Denedim ve bu harika!
Jim, Teksas

3

İyi bir referansa ek olarak, gerçekten öğrenme şekliniz iyi öğrenme araçlarını kullanmaktır. Bir tanesi açık kaynak kodlu Vim editörünü iki seçenekle birlikte kullanıyor:

  1. : komut satırına bir arama deseni yazarken incsearch ... ayarını yaparken, anında editör tam olarak eşleşen ile eşleşen ve onu vurgulayan ilk metin parçasına atlar. Artık hiçbir şeyle eşleşmeyecek bir şey yazarsanız, Vim imlecinizi başladığınız yere geri atlar.
  2. : set hlsearch ... bu, Vim'e geçerli RE aramayla eşleşen tüm metinlerde vurgulanmış bir arka plan göstermesini söyler.

Diğer RegExCoach ücretsiz bir araç çağrısı kullanmaktır . Aramak istediğiniz metni yapıştırın, ardından başka bir pencerede normal ifadenizi geliştirin. Vim gibi, anında başarılı maçlar vurgular.


RegExCoach şimdi bir shareware. Perl tarzı karmaşık RE'ler geliştirmede çok yardımcı oldum.
Firstrock

2

Basit bir dize karşılaştırması ile başlarsınız. Çok kolay, ama o kadar da güçlü değil.

Daha sonra, "Yunan" ve "GreeK" eşit karşılaştırmak için büyük / küçük harfe duyarlı karşılaştırmalar yapmanız gerekebilir. Bu biraz daha güçlü.

Yazımdaki küçük farklılıklar fark ettiğinizde bir gün 2 kelimenin eşit karşılaştırılmasını engellememelidir: yani "organize" ve "organize" eşit karşılaştırmalıdır. Oturur ve bunu yapan bir kod yazarsınız ve mutlusunuzdur.

Biraz daha soyutlamadan ve bazen "ize" ile biten tüm kelimelerin kardeşlerinin İngiliz yazımındaki eşitleriyle karşılaştırılmasını istediğinizi fark edinceye kadar. Veya, bazı karakter dizilerinin tekrarı belirli bir süredir. Ve elbette, hepsini birleştirmelisin.

Ve bunun gibi. Son olarak, büyük olasılıkla, her karakterin kendisi için durmadığı bir açıklama ile bitirdiniz. Başka hiçbir şey bir regexp değildir. Bir dizi dizenin açıklaması olarak görülebilir.

Ve sonra, oldukça kolaydır ve aşağıdaki 3 temel ilkeye iner:

Temel regexps'leriniz var: karakterleri, karakter sınıflarını, kullanışlı ve çok büyük olmayan harfler için \ d veya \ p {Lu} gibi karakter sınıflarının kısaltmaları.

Ve sonra, onları birleştirmek için bazı imkanlarınız var: eğer r1 ve r2 regexps ise, o zaman r1r2 r1 | r2 (r1).

Son fakat en az tekrarlayan değiştiriciler: r? r * r + r {n, m}

Bilmeniz gereken çoğu şey bu. İhtiyacınız olduğunda arayabileceğiniz herhangi bir şey.


2

Diğer iki iyi cevap size regex'lerin ardındaki teoriyi öğrenmenizi ve her ikisi de büyük tavsiye olan pratik yapmayı söyler. Ayrıca, ciddi olmanız durumunda size yardımcı olacak iyi bir görsel regex aracı almanızı tavsiye ederim.

RegexBuddy , örneğin, bir regex'in uygulamasında adım atmanıza izin veren görsel bir hata ayıklama moduna sahiptir ve regex motorunun her adımda ne yaptığını vurgulayan ve açıklayıcı bir metinle gösterir. Bu hata ayıklamayı kendi sitelerinde gösteren bir video var .



1

Benim için, regexp'in neyi eşleştirdiğini görmek benim hayatımı kolaylaştırıyor ve onları daha iyi anlamama yardımcı oldu.

Bunu yapmak için Emacs'ta hedef metni içeren bir dosya açacağım ve sonra isearch-forward-regexpkomutu kullanacağım . Düzenli ifadeye girdiğinizde, Emacs size neyin eşleştiğini gösterir (bu "isearch" kısmıdır).

Komutu çalıştırmak için Emacs'ta kullanabilirsiniz <ESC>xisearch-forward-regexp.


1

Sözlüksel çözümleyicileri ve ayrıştırıcıları oluşturmak için kullanılan esnek ve bizonu öğrenerek düzenli ifadeler öğrendim. Düzenli ifadeler olmadan bir ayrıştırıcınız olamazdı ve lexx ve yacc kitabı teoride çok hızlı hareket etmeden yürürken inanılmaz derecede iyi.

Temel olarak, günümüzde pratik olarak tüm regex motorları aynı prensipleri izlemektedir. Hepsi sonlu durumlu makinelerdir ve bunu gerçekten hakediyorsanız, yazdığınız hemen hemen tüm kodlara ayak uydurursunuz. Bu öğrenme özyinelemesine benzer şekilde, bir kez edindiğinizde, içgüdüsel olarak problemlere uygularsınız. Doğru aletle çözmek kolaydır, ancak onsuz çok zordur.

Normal ifadeler karşılaştırıldığında, Lexx ve yacc öğrenme hakkında başka bir şey, onlar nasıl öğrenmek olduğunu işe içten. Program nasıl ileriye bakar, niçin bir eşleşmeyi bitirir, verileri nasıl tutar ve çok daha fazlası. İşaretçileri anlamak mutlak bir zorunluluktur, ancak eğer lexx ve yacc alırsanız ve baştan baştan ilerlerseniz, istediğiniz her şeyi öğreneceksiniz ve kariyerinizin geri kalanı için çok güçlü bir araca sahip olacaksınız.

Bu soru öğrenme için bir sürü kaynak ve birlikte attığım esnek bir iskeleti içeriyor.


1

Artık, sorunu çözmenin / dizgiyi "tokenize etmenin" daha kolay bir yolu olmadığından emin olmaya çalışıyorum.

Bir tane bulamadığınızda, diziden ne istediğinizi eşleştirmeye çalışmak yerine bir problem olarak bakıyorum, bunun yerine istemediğiniz şeyi eşleştirmemek meselesidir. Bunun nedeni çoğunlukla regex'in açgözlü olmasıdır. Ama istediğimi elde etmek için bir yaklaşım olarak bana hizmet etti.

İşte bir örnek:

string = "Sep 22 19:57:38 host fcron[9137]: \
          Job fbsetbg -r $HOME/backgrounds/ \
          started for user user (pid 9138)"

dakikayı eşleştirmek için:

string.match /^\w+\s\d+\s\d+:(\d+):\d+\s\w+\s/ # correct but bad
string.match /\d+:([^:]+):\d+/                 # correct and good

Başka her şeyle birlikte zamanı bulmaya çalışmak yerine, farklı sınırları bulmaya çalışın.

Örnek biraz tartışmalı, ancak bulabildiğim her şey.


1

Benim kullandığım yaklaşımlardan biri, sözdizimi güncellemelerine ihtiyaç duyan bir sürü açık kaynaklı proje bulmak ve daha sonra birçok düzenli ifadeden oluşan, gittikçe daha karmaşık olan bir betiği yazmaktı.

Betik, her açık kaynaklı projede birçok farklı dosyaya karşı çalışmalıydı. Daha sonra farklı tarzlarda birçok farklı projeye karşı koşun. Çok basit bir şeyle başladım %s/before/after o zaman bunun çok fazla olayla eşleştiğini gördüm. bu yüzden bunu önlemek için daha fazla şeyler ekledim. Sonra farklı değişiklikler gerektiren farklı sözdizimi stilleri kullanarak farklı projeler buldum.

Sonunda ben ile sona erdi

  • düzenli ifadeler hakkında harika bilgi ve beceriler
  • sed ile iyi beceriler
  • birçok açık kaynaklı projeye yardım etmek
  • github profilimde gösterilen çok sayıda katkı etkinliği alma
  • sanal araç kemeri için bir başka iyi 'İsviçre çakısı bıçağı' aracı

ve bu yaklaşımda ihtiyaç duyulan yardımcı oldu

  • hile yapmadan gerçek hedeflere ulaşmak
  • (regex) becerilerini daha fazla motivasyon ile daha büyük bir hedefin parçası olarak kullanın.
  • Başkalarının kodunu değiştirerek ve ardından değişiklikleri gözden geçirerek öğrendiğim becerilerin kanıtını gösterebilme.

Ayrıca, çeşitli diller için bir sürü site bulunduğunu da söyleyeceğim - yakut, javascript, vb. Bunlar:

bir sitede birden fazla dilde regexes

maç gruplarına odaklanın:


0

Çarpım tablosunu öğrenmeye benzer düzenli ifadeler öğrenirken buldum - evet, arkasındaki fikirleri anlamanız gerekiyor, ama sonuçta bunu sık sık ve tekrar tekrar yapmanız gerekiyor.

Öğrenirken kendime günde birkaç regex alıştırması yapma hedefi koyardım. Uygulamada bu, günde en az bir kez, ekranımdaki bir dizgiye veya metne bakmaya çalışacağım ve bir meydan okuma ile karşı karşıya kalacağım anlamına gelirdi - "tüm e-posta adreslerini buradan alabilir miyim" veya "tüm 'code' kelimesinin isimden ziyade bir fiil olarak kullanıldığı, "bunun gibi şeyler.

Bunu yapmak birkaç hafta için gerçekten ödedi - ve elbette periyodik gözden geçirmelere ve yenilemelere ihtiyaç var. Bir tane yüzünden olacağım.

Regex'i gerçek zamanlı olarak test etmeme izin verdiği için, bu çevrimiçi aracı da faydalı buldum: http://www.gethifi.com/tools/regex

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.