RegEx, XHTML kendi kendine yeten etiketler dışında açık etiketlerle eşleşir
Tüm bu açılış etiketlerini eşleştirmem gerekiyor:
<p>
<a href="foo">
Ama bunlar değil:
<br />
<hr class="foo" />
Bunu buldum ve doğru anladığımdan emin olmak istedim. Ben sadece a-z
.
<([a-z]+) *[^/]*?>
Sanırım şöyle diyor:
- Daha azını bul o zaman
- Bir veya daha fazla kez bul (ve yakala)
- Sıfır veya daha fazla boşluk bulun, sonra
- Sıfır veya daha çok kez, açgözlü hariç herhangi bir karakter bul
/
, sonra - Büyüktür bul
Buna hakkım var mı? Daha da önemlisi, ne düşünüyorsunuz?
Yanıtlar
[X] HTML'yi normal ifadeyle ayrıştıramazsınız. Çünkü HTML, normal ifade ile ayrıştırılamaz. Regex, HTML'yi doğru şekilde ayrıştırmak için kullanılabilecek bir araç değildir. Daha önce burada birçok kez HTML ve regex sorularını yanıtladığım gibi, regex kullanımı HTML tüketmenize izin vermez. Düzenli ifadeler, HTML tarafından kullanılan yapıları anlamak için yeterince karmaşık olmayan bir araçtır. HTML normal bir dil değildir ve bu nedenle normal ifadelerle ayrıştırılamaz. Normal ifade sorguları, HTML'yi anlamlı kısımlarına ayıracak donanıma sahip değildir. birçok kez ama bana ulaşmıyor. Perl tarafından kullanılan gelişmiş düzensiz düzenli ifadeler bile HTML'yi ayrıştırma görevine bağlı değildir. Beni asla çatlatamayacaksın. HTML, normal ifadelerle ayrıştırılamayacak kadar karmaşık bir dildir. Jon Skeet bile normal ifadeler kullanarak HTML'yi ayrıştıramaz. HTML'yi normal ifadelerle her ayrıştırmaya çalıştığınızda, kutsal olmayan çocuk bakirelerin kanını ağlatıyor ve Rus bilgisayar korsanları web uygulamanızı buluyor. HTML'yi regex ile ayrıştırmak, bozuk ruhları yaşayanların alemine çağırır. HTML ve regex aşk, evlilik ve ritüel bebek öldürme gibi bir araya gelir. <center> tutamıyor, çok geç. Aynı kavramsal alanda regex ve HTML'nin gücü, aklınızı çok sulu macun gibi yok edecek. HTML'yi regex ile ayrıştırırsanız, Onlara ve onların küfürlü yollarını, Adı Temel Çok Dilli Düzlemde ifade edilemeyen Kişi için insanlık dışı çalışmaya mahkum ediyor olursunuz. HTML-artı-regexp, siz gözlemlerken, zihninizin dehşet saldırısı içinde soldurulduğunu gözlemlerken, duyarlıların sinirlerini sıvılaştırır. Rege̿̔̉x tabanlı HTML ayrıştırıcıları, StackOverflow'u öldüren kanserdirçok geç çok geç kurtarılamayız bir çocuğun ihlali, normal ifadenin tüm canlı dokuları tüketmesini sağlar (daha önce öngörüldüğü gibi HTML hariç) sevgili efendim , ayrıştırmak için normal ifadeyi kullanarak bu beladan nasıl kurtulabilir? HTML, HTML'yi işlemek için bir araç olarak rege x'i kullanarak insanlığı korkunç bir işkenceye ve güvenlik açıklarına mahkum etti, bu dünya ile korkunç varlıkların (SGML varlıkları gibi, ancak daha yozlaşmış) sadece bir bakış açısı arasında bir boşluk oluşturuyor . reg dünyası HTML ex ayrıştırıcıları olacak ins rı değerlendirilerek taşıma ap rogrammer bilinci i nto aw orl d durmayan çığlık, o gelir
, pestilent sl
ithy regex enfeksiyon wil sizin HT bitirip l için ML ayrıştırıcı, uygulama ve varoluş Visual Basic gibi her zaman sadece kötü o com geliyor es olmayan fi yapmak GHT h e geliyor, selam lar kutsal olmayan Radiance de HTML etiketleri tüm aydınlanma stro҉ying sızdıran fr̶ǫm yo ur gözleri gibi liq uid p düzenli ain, şarkı exp yeniden
salgılanması ayrıştırma
exti edecek mor seslerini nguish sp tal adam burada ben bunu güzel t görebileceği görebilirsiniz o f inal snuf
fing o f yalan s Man TÜM Lost ait LL Ben SL inci OST o gelecek midilli e o com s
o co es
bana
st o ich veya permeat es al l MY FAC e yüzümü ᵒh tanrı n o HAYIR noO Ç AÇIK Θ durdurma t o bir * ̶͑̾̾ gl es n ot rè̑ͧ̌aͨl̘̝̙̃ͤ͂̾̆ ZA̡͊͠͝LGΌ ISͮ̂҉̯͈͕̹̘̱ T O͇̹̺ͅƝ̴ȳ̳ TH̘ Ë͖́̉ ͠P̯͍̭O̚ N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝ S̨̥̫͎̭ͯ̿̔̀ͅ
͎a̧͈͖r̽̾̈́͒͑e
Bunun yerine bir XML ayrıştırıcı kullanmayı denediniz mi?
Moderatörün Notu
Bu gönderi, içeriğinde uygun olmayan düzenlemeleri önlemek için kilitlendi. Gönderi tam olarak görünmesi gerektiği gibi görünüyor - içeriğiyle ilgili herhangi bir sorun yok. Lütfen dikkatimiz için işaretlemeyin.
İken keyfi HTML sadece regex imkansızdır ile, bazen bir ayrıştırma için bunları kullanmak için uygun olan sınırlı bilinen HTML kümesi.
Verileri kazıyıp sonra bir veritabanına yerleştirmek istediğiniz küçük bir HTML sayfaları kümeniz varsa, normal ifadeler iyi çalışabilir. Örneğin, yakın zamanda Parlamentonun web sitesinden çıkardığım Avustralya federal Temsilcilerinin adlarını, partilerini ve bölgelerini almak istedim. Bu sınırlı, tek seferlik bir işti.
Regexes benim için gayet iyi çalıştı ve kurulumu çok hızlıydı.
Bence buradaki kusur, HTML'nin bir Chomsky Type 2 dilbilgisi (bağlamdan bağımsız dilbilgisi) olması ve normal ifadenin bir Chomsky Type 3 dilbilgisi (normal dilbilgisi) olmasıdır . Tip 2 dilbilgisi, Tip 3 dilbilgisinden temelde daha karmaşık olduğu için (bkz. Chomsky hiyerarşisi ), XML'i normal bir ifadeyle ayrıştırmak matematiksel olarak imkansızdır .
Ancak çoğu deneyecek ve hatta bazıları başarıyı iddia edecek - ancak diğerleri hatayı bulana ve sizi tamamen alt üst edene kadar.
Bu adamları dinleme. Tamamen olabilir daha küçük parçalar halinde görevi bölerseniz regex ile bağlam bağımsız gramerler ayrıştırmak. Doğru kalıbı, bunların her birini sırayla yapan bir komut dosyasıyla oluşturabilirsiniz:
- Durdurma Problemini Çöz.
- Bir daire çizin.
- O (log n) veya daha düşük bir seviyede Seyahat Eden Satıcı Problemini çözün. Bundan daha fazlası varsa, RAM'iniz bitecek ve motor kapanacaktır.
- Desen oldukça büyük olacaktır, bu nedenle rastgele verileri kayıpsız bir şekilde sıkıştıran bir algoritmanız olduğundan emin olun.
- Neredeyse bitti - sadece hepsini sıfıra böl. Basit.
Son bölümü tam olarak bitirmedim ama yaklaştığımı biliyorum. Bir CthulhuRlyehWgahnaglFhtagnException
sebepten dolayı s atmaya devam ediyor , bu yüzden onu VB 6'ya taşıyacağım ve kullanacağım On Error Resume Next
. Duvarda yeni açılan bu garip kapıyı araştırdığımda kodla güncelleme yapacağım. Hmm.
Not: Pierre de Fermat bunun nasıl yapılacağını da çözdü, ancak yazdığı kenar boşluğu kod için yeterince büyük değildi.
Sorumluluk reddi : seçeneğiniz varsa bir ayrıştırıcı kullanın. Bahsedilen...
Bu, HTML etiketleriyle eşleştirmek için kullandığım (!) Normal ifade:
<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>
Mükemmel olmayabilir, ancak bu kodu çok fazla HTML üzerinden çalıştırdım . <a name="badgenerator"">
Web'de görünen gibi garip şeyleri bile yakaladığını unutmayın .
Sanırım kendi içinde yer alan etiketlerle eşleşmemesini sağlamak için, ya Kobi'nin negatif arkasına bakmayı kullanmak istersiniz :
<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/\s*)>
veya sadece eğer ve değilse birleştirin.
Olumsuz oy kullananlara: Bu, gerçek bir üründen çalışan koddur. Bu sayfayı okuyan herkesin HTML'de normal ifadeler kullanmanın sosyal olarak kabul edilebilir olduğu izlenimini edineceğinden şüpheliyim.
Uyarı : Bu normal ifadenin CDATA blokları, yorumlar ve komut dosyası ve stil öğeleri varlığında hala bozulduğunu not etmeliyim. İyi haber şu ki, normal ifade kullananlardan kurtulabilirsiniz ...
Size Dünya'nın yuvarlak olduğunu (veya garip kelimeler kullanmak istiyorlarsa Dünya'nın basık bir sferoid olduğunu) söyleyecek insanlar var. Yalan söylüyorlar.
Normal İfadelerin yinelemeli olmaması gerektiğini söyleyecek insanlar var. Sizi sınırlıyorlar. Size boyun eğdirmeleri gerekiyor ve bunu sizi cehalet içinde tutarak yapıyorlar.
Onların gerçekliğinde yaşayabilir veya kırmızı hapı alabilirsin.
Lord Marshal gibi (Marshal .NET sınıfının bir akrabası mı?),
Underverse Stack Based Regex- Verse'i
gördüm ve
hayal edemeyeceğiniz
güç
bilgileriyle geri döndüm
. Evet, sanırım onları koruyan bir ya da iki tane vardı, ama televizyonda futbol izliyorlardı, bu yüzden zor olmadı.
XML durumunun oldukça basit olduğunu düşünüyorum. RegEx (.NET sözdiziminde), zayıf zihniniz tarafından anlaşılmasını kolaylaştırmak için base64'te söndürülmüş ve kodlanmış, aşağıdaki gibi bir şey olmalıdır:
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
+r/vD34mUADO1P4/AQAA//8=
Ayarlanacak seçenekler RegexOptions.ExplicitCapture
. Aradığınız yakalama grubu ELEMENTNAME
. Yakalama grubu ERROR
boş değilse, bir ayrıştırma hatası vardı ve Regex durdu.
Bunu insan tarafından okunabilir bir normal ifadeye dönüştürmede sorun yaşıyorsanız, bu size yardımcı olacaktır:
static string FromBase64(string str)
{
byte[] byteArray = Convert.FromBase64String(str);
using (var msIn = new MemoryStream(byteArray))
using (var msOut = new MemoryStream()) {
using (var ds = new DeflateStream(msIn, CompressionMode.Decompress)) {
ds.CopyTo(msOut);
}
return Encoding.UTF8.GetString(msOut.ToArray());
}
}
Emin değilseniz, hayır, şaka yapmıyorum (ama belki yalan söylüyorum). Çalışacak. Test etmek için tonlarca birim testi yaptım ve hatta uygunluk testlerini (bir kısmını) kullandım . Tam gelişmiş bir ayrıştırıcı değil, bir belirteç oluşturucudur, bu nedenle XML'i yalnızca bileşen belirteçlerine böler. DTD'leri ayrıştırmaz / entegre etmez.
Oh ... regex'in kaynak kodunu bazı yardımcı yöntemlerle istiyorsanız:
bir xml veya tam düz normal ifadeyi belirtmek için normal ifade
Kabukta, sed kullanarak HTML'yi ayrıştırabilirsiniz :
- Turing.sed
- HTML ayrıştırıcı yaz (ev ödevi)
- ???
- Kar!
Alakalı (neden normal ifade eşleşmesini kullanmamalısınız):
- Normal İfadeleri Bu Kadar Seviyorsanız Neden Onlarla Evlenmiyorsunuz?
- Normal İfadeler: Artık İki Probleminiz Var
- Stackoverflow.com'un HTML temizleyicisini hacklemek
XML'yi ve özellikle HTML'yi ayrıştırmak için doğru aracın bir normal ifade motoru değil, bir ayrıştırıcı olduğunu kabul ediyorum . Bununla birlikte, diğerlerinin de belirttiği gibi, bazen bir normal ifade kullanmak daha hızlı, daha kolaydır ve veri formatını biliyorsanız işi bitirir.
Microsoft aslında .NET Framework'te Normal İfadeler için En İyi Uygulamalar bölümüne sahiptir ve özellikle Girdi Kaynağının Değerlendirilmesi hakkında konuşur .
Normal İfadelerin sınırlamaları vardır, ancak aşağıdakileri düşündünüz mü?
.NET çerçevesi, Dengeleme Grubu Tanımlarını desteklemesi açısından normal ifadeler söz konusu olduğunda benzersizdir .
- Dengeli Yapıları .NET Normal İfadeleriyle Eşleştirme konusuna bakın
- Bkz. .NET Düzenli İfadeler: Normal İfade ve Dengeli Eşleme
- Dengeleme Grubu Tanımları ile ilgili Microsoft belgelerine bakın
Bu nedenle, XML'i normal ifadeler kullanarak çözümleyebileceğinize inanıyorum. Bununla birlikte, bunun geçerli XML olması gerektiğini unutmayın ( tarayıcılar HTML'yi çok affeder ve HTML içinde kötü XML sözdizimine izin verir ). Bu, "Dengeleme Grubu Tanımı" normal ifade motorunun bir PDA görevi görmesine izin vereceği için mümkündür.
Yukarıda alıntı yapılan 1. maddeden alıntı:
.NET Normal İfade Motoru
Yukarıda tarif edildiği gibi, uygun şekilde dengelenmiş yapılar, bir düzenli ifade ile tarif edilemez. Ancak, .NET düzenli ifade motoru, dengeli yapıların tanınmasına izin veren birkaç yapı sağlar.
(?<group>)
- Yakalanan sonucu, isim grubu ile yakalama yığınına iter.(?<-group>)
- Yakalama yığınından ad grubu ile en çok yakalamayı açar.(?(group)yes|no)
- isim grubuna sahip bir grup varsa evet bölümüyle eşleşir, aksi takdirde no bölümü ile eşleşir.Bu yapılar, bir .NET düzenli ifadesinin, temelde yığın işlemlerinin basit sürümlerine izin vererek kısıtlı bir PDA taklit etmesine izin verir: push, pop ve empty. Basit işlemler, sırasıyla artırma, azaltma ve sıfırla karşılaştırmaya hemen hemen eşdeğerdir. Bu, .NET düzenli ifade motorunun bağlamdan bağımsız dillerin bir alt kümesini, özellikle de yalnızca basit bir sayaç gerektirenleri tanımasına olanak tanır. Bu da geleneksel olmayan .NET normal ifadelerinin düzgün bir şekilde dengelenmiş bireysel yapıları tanımasına izin verir.
Aşağıdaki normal ifadeyi düşünün:
(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
<!-- .*? --> |
<[^>]*/> |
(?<opentag><(?!/)[^>]*[^/]>) |
(?<-opentag></[^>]*[^/]>) |
[^<>]*
)*
(?(opentag)(?!))
Bayrakları kullanın:
- Tek satır
- IgnorePatternWhitespace (regex'i daraltıp tüm beyaz boşlukları kaldırırsanız gerekli değildir)
- IgnoreCase (gerekli değil)
Normal İfade Açıklaması (satır içi)
(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don't backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/> | # self closing tag
(?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag></[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack
Bunu A Better .NET Normal İfade Sınayıcısı'nda deneyebilirsiniz .
Örnek kaynağı kullandım:
<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
Bu eşleşmeyi buldu:
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
aslında şu şekilde ortaya çıkmasına rağmen:
<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another >ul<, oh my!</li> <li>...</li> </ul> </div> </li> </ul>
Son olarak, Jeff Atwood'un şu makalesinden gerçekten keyif aldım: Html'i Cthulhu Yolu Ayrıştırma . Yeterince komik, şu anda 4k'nin üzerinde oyu olan bu sorunun cevabını veriyor.
PHP'de XML ve HTML'yi ayrıştırmak için QueryPath kullanmanızı öneririm . Temelde jQuery ile hemen hemen aynı sözdizimi, sadece sunucu tarafında.
HTML'yi normal ifadelerle ayrıştıramayacağınız yanıtlar doğru olsa da, burada geçerli değildir. OP sadece bir HTML etiketini normal ifadelerle ayrıştırmak ister ve bu, normal ifadelerle yapılabilecek bir şeydir.
Ancak önerilen normal ifade yanlıştır:
<([a-z]+) *[^/]*?>
Eğer geriye tarafından, regex şey eklerseniz gibi aptalca şeyler maç zorunda olabilir <a >>
, [^/]
çok keyfi olduğunu. Ayrıca <space>*[^/]*
, [^/]*
boşluklarla da eşleşebileceğinden , bunun gereksiz olduğunu unutmayın .
Benim önerim olurdu
<([a-z]+)[^>]*(?<!/)>
(?<! ... )
Negatif bakış nerede (Perl regexlerinde). "A <, sonra bir kelime, sonra a> olmayan herhangi bir şey, sonuncusu a / olmayabilir, ardından>" yazıyor.
Bunun <a/ >
(tıpkı orijinal normal ifade gibi) gibi şeylere izin verdiğini unutmayın, bu nedenle daha kısıtlayıcı bir şey istiyorsanız, boşluklarla ayrılmış öznitelik çiftlerini eşleştirmek için bir normal ifade oluşturmanız gerekir.
Deneyin:
<([^\s]+)(\s[^>]*?)?(?<!/)>
Sizinkine benzer, ancak sonuncusu >
eğik çizgiden sonra olmamalıdır ve aynı zamanda kabul eder h1
.
Eski bir Çinli stratejist, general ve filozof Sun Tzu şunları söyledi:
Düşmanlarınızı tanır ve kendinizi tanırsanız tek bir kayıp olmadan yüz savaşı kazanabileceğiniz söyleniyor. Sadece kendinizi tanıyorsanız, ancak rakibinizi bilmiyorsanız, kazanabilir veya kaybedebilirsiniz. Ne kendinizi ne de düşmanınızı tanımıyorsanız, her zaman kendinizi tehlikeye atarsınız.
Bu durumda düşmanınız HTML'dir ve siz ya kendinizsiniz ya da regexsiniz. Hatta düzensiz regex içeren Perl bile olabilirsiniz. HTML'yi bilin. Kendini bil.
HTML'nin doğasını açıklayan bir haiku yazdım.
HTML has
complexity exceeding
regular language.
Ayrıca, Perl'de regex'in doğasını anlatan bir haiku da besteledim.
The regex you seek
is defined within the phrase
<([a-zA-Z]+)(?:[^>]*[^/]*)?>
<?php
$selfClosing = explode(',', 'area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'); $html = '
<p><a href="#">foo</a></p>
<hr/>
<br/>
<div>name</div>';
$dom = new DOMDocument(); $dom->loadHTML($html); $els = $dom->getElementsByTagName('*'); foreach ( $els as $el ) { $nodeName = strtolower($el->nodeName); if ( !in_array( $nodeName, $selfClosing ) ) { var_dump( $nodeName );
}
}
Çıktı:
string(4) "html"
string(4) "body"
string(1) "p"
string(1) "a"
string(3) "div"
Temel olarak, kendi kendine kapanan öğe düğüm adlarını tanımlayın, tüm html dizesini bir DOM kitaplığına yükleyin, tüm öğeleri alın, döngü yapın ve kendi kendine kapanmayanları filtreleyin ve üzerlerinde çalışın.
Eminim şimdiye kadar bu amaçla regex kullanmamanız gerektiğini zaten biliyorsunuzdur.
Buna tam olarak ihtiyacınızı bilmiyorum, ancak .NET kullanıyorsanız, Html Çeviklik Paketi kullanamaz mısınız?
Alıntı:
"Web dışında" HTML dosyalarını ayrıştırmanıza izin veren bir .NET kod kitaplığıdır. Ayrıştırıcı, "gerçek dünyada" hatalı biçimlendirilmiş HTML’ye çok toleranslıdır.
>
Birinin önünde olmayan ilkini istiyorsunuz /
. Bunun nasıl yapılacağına ilişkin ayrıntılar için buraya bakın . Geriye negatif bakış olarak adlandırılır.
Bununla birlikte, bunun naif bir uygulaması <bar/></foo>
bu örnek belgede eşleşecektir.
<foo><bar/></foo>
Çözmeye çalıştığınız sorun hakkında biraz daha bilgi verebilir misiniz? Programatik olarak etiketler arasında yineliyor musunuz?
W3C, sözde regexp biçiminde ayrıştırmayı açıklar:
W3C Bağlantısı
İçin var bağlantıları izleyin QName
, S
ve Attribute
daha net bir görüntü elde etmek.
Buna dayanarak, etiketleri soyma gibi şeyleri işlemek için oldukça iyi bir regexp oluşturabilirsiniz.
PHP için buna ihtiyacınız varsa:
PHP DOM fonksiyonları düzgün XML biçimlendirilir sürece düzgün çalışmaz. Geri kalan insanlık için kullanımları ne kadar iyi olursa olsun.
simplehtmldom iyidir, ancak biraz hatalı buldum ve hafızası oldukça ağır [Büyük sayfalarda çökecek.]
Querypath'i hiç kullanmadım , bu yüzden yararlılığı hakkında yorum yapamam.
Deneyebileceğim başka bir tane de , kaynaklar konusunda çok hafif olan ve bir süredir mutlu bir şekilde kullanıyorum olan DOMParser'ım . Öğrenmesi basit ve güçlü.
Python ve Java için benzer bağlantılar yayınlanmıştır.
Olumsuz oy verenler için - Sınıfımı yalnızca XML ayrıştırıcıları gerçek kullanıma dayanamadığı zaman yazdım. Dini olumsuz oylama, sadece yararlı yanıtların gönderilmesini engeller - olayları sorunun perspektifinde tutun lütfen.
İşte çözüm:
<?php
// here's the pattern:
$pattern = '/<(\w+)(\s+(\w+)\s*\=\s*(\'|")(.*?)\\4\s*)*\s*(\/>|>)/'; // a string to parse: $string = 'Hello, try clicking <a href="#paragraph">here</a>
<br/>and check out.<hr />
<h2>title</h2>
<a name ="paragraph" rel= "I\'m an anchor"></a>
Fine, <span title=\'highlight the "punch"\'>thanks<span>.
<div class = "clear"></div>
<br>';
// let's get the occurrences:
preg_match_all($pattern, $string, $matches, PREG_PATTERN_ORDER); // print the result: print_r($matches[0]);
?>
Derinlemesine test etmek için, otomatik kapanma etiketlerine aşağıdaki gibi girdim:
- <hr />
- <br/>
- <br>
Ayrıca şu etiketleri de girdim:
- bir özellik
- birden fazla öznitelik
- değerin tek tırnağa veya çift tırnağa bağlı olduğu özellikler
- Sınırlayıcı çift tırnak olduğunda tek tırnak içeren öznitelikler ve tam tersi
- "=" simgesinden önce, sonra ve hem önünde hem de sonrasında boşluk bulunan "güzel" öznitelikleri.
Yukarıdaki kavram kanıtında işe yaramayan bir şey bulursanız, becerilerimi geliştirmek için kodu analiz etmeye hazırım.
<DÜZENLEME> Kullanıcıdan gelen sorunun kendi kendine kapanan etiketlerin ayrıştırılmasını önlemek olduğunu unuttum. Bu durumda model daha basittir ve şuna dönüşür:
$pattern = '/<(\w+)(\s+(\w+)\s*\=\s*(\'|")(.*?)\\4\s*)*\s*>/';
@Ridgerunner kullanıcısı, desenin alıntılanmamış özniteliklere veya değer içermeyen özniteliklere izin vermediğini fark etti . Bu durumda bir ince ayar bize şu kalıbı getirir:
$pattern = '/<(\w+)(\s+(\w+)(\s*\=\s*(\'|"|)(.*?)\\5\s*)?)*\s*>/';
</EDIT>
Deseni anlamak
Birisi model hakkında daha fazla bilgi edinmekle ilgileniyorsa, bir satır sunuyorum:
- ilk alt ifade (\ w +) etiket adıyla eşleşir
- ikinci alt ifade, bir özniteliğin modelini içerir. Şunlardan oluşur:
- bir veya daha fazla boşluk +
- özniteliğin adı (\ w +)
- sıfır veya daha fazla boşluk * (mümkün veya değil, burada boşluk bırakarak)
- "=" sembolü
- yine sıfır veya daha fazla beyaz boşluk
- öznitelik değerinin sınırlayıcısı, tek veya çift tırnak ('| "). Örüntüde, tek tırnak, PHP dize sınırlayıcısıyla çakıştığı için öncelenmiştir. Bu alt ifade, başvurulabilmesi için parantezlerle yakalanır yine özniteliğin kapanışını ayrıştırmak, bu yüzden çok önemlidir.
- hemen hemen her şeyle eşleşen özniteliğin değeri : (. *?); bu belirli sözdiziminde, açgözlü eşleşmeyi (yıldız işaretinden sonraki soru işareti) kullanarak RegExp motoru, bu alt ifadeden sonra gelenlerden başka her şeyle eşleşen "ileriye bakma" benzeri bir işleci etkinleştirir
- işte eğlence geliyor: \ 4 kısmı, modelde daha önce tanımlanan bir alt ifadeye başvuran bir geri referans operatörüdür , bu durumda, bulunan ilk öznitelik sınırlayıcısı olan dördüncü alt ifadeye atıfta bulunuyorum
- sıfır veya daha fazla boşluk *
- öznitelik alt ifadesi, yıldız işareti ile verilen sıfır veya daha fazla olası oluşumun belirtilmesiyle burada biter.
- Daha sonra, bir etiket ">" sembolünden önce bir boşlukla bitebileceğinden, sıfır veya daha fazla boşluk \ s * alt şablonu ile eşleştirilir.
- Eşleştirilecek etiket, basit bir ">" sembolüyle veya ondan önceki eğik çizgiyi kullanan olası bir XHTML kapanışı ile bitebilir: (/> |>). Eğik çizgi, normal ifade sınırlayıcısıyla çakıştığı için elbette kaçtı.
Küçük ipucu: Bu kodu daha iyi analiz etmek için, HTML özel karakterlerinin kaçışını sağlamadığım için oluşturulan kaynak koda bakmak gerekir.
Bir HTML belgesinden hızlı bir şekilde bir şey çıkarmam gerektiğinde, bunu XML'e dönüştürmek için Tidy'yi ve ardından ihtiyacım olanı elde etmek için XPath veya XSLT'yi kullanıyorum. Sizin durumunuzda, bunun gibi bir şey:
//p/a[@href='foo']
Daha önce HTMLParser adlı açık kaynaklı bir araç kullandım . HTML'yi çeşitli şekillerde ayrıştırmak için tasarlanmıştır ve amaca oldukça iyi hizmet eder. HTML'yi farklı ağaç modları olarak ayrıştırabilir ve düğümden öznitelikleri almak için API'sini kolayca kullanabilirsiniz. Kontrol edin ve bunun size yardımcı olup olamayacağını görün.
HTML'yi normal ifadelerle ayrıştırmayı seviyorum. Kasıtlı olarak bozulmuş aptal HTML'yi ayrıştırmaya çalışmıyorum. Bu kod benim ana ayrıştırıcımdır (Perl sürümü):
$_ = join "",<STDIN>; tr/\n\r \t/ /s; s/</\n</g; s/>/>\n/g; s/\n ?\n/\n/g; s/^ ?\n//s; s/ $//s; print
Buna htmlsplit denir , her satırda bir etiket veya metin parçası olacak şekilde HTML'yi satırlara böler. Daha sonra satırlar grep , sed , Perl, vb. Gibi diğer metin araçları ve komut dosyaları ile daha fazla işlenebilir . Şaka bile yapmıyorum :) Keyfini çıkarın.
Eğer muazzam web sayfalarını işlemek istiyorsanız, her şeyden önce olan Perl betiğimi güzel bir akış haline getirmek yeterince basit. Ama gerçekten gerekli değil.
HTML Bölme
Bazı daha iyi normal ifadeler:
/(<.*?>|[^<]+)\s*/g # Get tags and text
/(\w+)="(.*?)"/g # Get attibutes
XML / XHTML için iyidirler.
Küçük varyasyonlarla, karışık HTML ile başa çıkabilir ... veya önce HTML -> XHTML'yi dönüştürebilir.
Normal ifadeler yazmanın en iyi yolu , opak tek satırlılar veya yorumlu çok satırlı canavarlar kadar değil , Lex / Yacc stilindedir. Bunu burada henüz yapmadım; bunlara zar zor ihtiyaç duyuyor.
Burada, HTML'yi bir miktar regex kullanarak ayrıştıran PHP tabanlı bir ayrıştırıcı var. Bu projenin yazarı olarak, HTML'yi regex ile ayrıştırmanın mümkün olduğunu ancak verimli olmadığını söyleyebilirim. Bir sunucu tarafı çözüme ihtiyacınız varsa ( wp-Typography WordPress eklentim için yaptığım gibi ), bu işe yarıyor.
HTML'yi BBCode ile değiştirmek için burada bazı güzel normal ifadeler var . Siz muhalifler için, onun HTML'yi tam olarak ayrıştırmaya çalışmadığını, sadece sterilize etmeye çalıştığını unutmayın. Muhtemelen basit "ayrıştırıcısının" anlayamayacağı etiketleri ortadan kaldırmayı göze alabilir.
Örneğin:
$store =~ s/http:/http:\/\//gi; $store =~ s/https:/https:\/\//gi;
$baseurl = $store;
if (!$query->param("ascii")) { $html =~ s/\s\s+/\n/gi;
$html =~ s/<pre(.*?)>(.*?)<\/pre>/\[code]$2\[\/code]/sgmi;
}
$html =~ s/\n//gi; $html =~ s/\r\r//gi;
$html =~ s/$baseurl//gi;
$html =~ s/<h[1-7](.*?)>(.*?)<\/h[1-7]>/\n\[b]$2\[\/b]\n/sgmi;
$html =~ s/<p>/\n\n/gi; $html =~ s/<br(.*?)>/\n/gi;
$html =~ s/<textarea(.*?)>(.*?)<\/textarea>/\[code]$2\[\/code]/sgmi;
$html =~ s/<b>(.*?)<\/b>/\[b]$1\[\/b]/gi;
$html =~ s/<i>(.*?)<\/i>/\[i]$1\[\/i]/gi;
$html =~ s/<u>(.*?)<\/u>/\[u]$1\[\/u]/gi;
$html =~ s/<em>(.*?)<\/em>/\[i]$1\[\/i]/gi;
$html =~ s/<strong>(.*?)<\/strong>/\[b]$1\[\/b]/gi;
$html =~ s/<cite>(.*?)<\/cite>/\[i]$1\[\/i]/gi;
$html =~ s/<font color="(.*?)">(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi; $html =~ s/<font color=(.*?)>(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi;
$html =~ s/<link(.*?)>//gi; $html =~ s/<li(.*?)>(.*?)<\/li>/\[\*]$2/gi; $html =~ s/<ul(.*?)>/\[list]/gi;
$html =~ s/<\/ul>/\[\/list]/gi; $html =~ s/<div>/\n/gi;
$html =~ s/<\/div>/\n/gi; $html =~ s/<td(.*?)>/ /gi;
$html =~ s/<tr(.*?)>/\n/gi; $html =~ s/<img(.*?)src="(.*?)"(.*?)>/\[img]$baseurl\/$2\[\/img]/gi;
$html =~ s/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/\[url=$baseurl\/$2]$4\[\/url]/gi;
$html =~ s/\[url=$baseurl\/http:\/\/(.*?)](.*?)\[\/url]/\[url=http:\/\/$1]$2\[\/url]/gi;
$html =~ s/\[img]$baseurl\/http:\/\/(.*?)\[\/img]/\[img]http:\/\/$1\[\/img]/gi; $html =~ s/<head>(.*?)<\/head>//sgmi;
$html =~ s/<object>(.*?)<\/object>//sgmi; $html =~ s/<script(.*?)>(.*?)<\/script>//sgmi;
$html =~ s/<style(.*?)>(.*?)<\/style>//sgmi; $html =~ s/<title>(.*?)<\/title>//sgmi;
$html =~ s/<!--(.*?)-->/\n/sgmi; $html =~ s/\/\//\//gi;
$html =~ s/http:\//http:\/\//gi; $html =~ s/https:\//https:\/\//gi;
$html =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gsi; $html =~ s/\r\r//gi;
$html =~ s/\[img]\//\[img]/gi; $html =~ s/\[url=\//\[url=/gi;
(X) HTML'yi ayrıştırmak için düzenli ifade yöntemleri sorusuyla ilgili olarak, bazı sınırlardan bahsedenlerin yanıtı şudur: Bu güçlü silahın gücünü yönetecek kadar eğitilmediniz, çünkü burada kimse özyineleme hakkında konuşmadı .
İfadeden bağımsız bir meslektaşım, bu tartışmayı bana bildirdi ki bu, bu eski ve sıcak konu hakkında internette kesinlikle ilk değil.
Bazı gönderileri okuduktan sonra, ilk yaptığım şey bu ileti dizisindeki "? R" dizesini aramak oldu. İkincisi "özyineleme" hakkında araştırma yapmaktı.
Hayır, kutsal inek, eşleşme bulunamadı. Bir ayrıştırıcının üzerine inşa edildiği ana mekanizmadan kimse bahsetmediğinden, kısa süre sonra kimsenin bunu anlamadığını fark ettim.
Bir (x) HTML ayrıştırıcısının özyinelemeye ihtiyacı varsa, özyinelemesiz bir normal ifade ayrıştırıcısı bu amaç için yeterli değildir. Bu basit bir yapı.
Düzenli ifadelerin siyah sanatını güç olduğunu , bu yüzden belki çalışıyor ve bir elinde tüm web yakalamak için kişisel çözüm test ederken biz dışarı sol seçenek daha vardır ... Eh, bu konuda eminim :)
İşte sihirli model:
$pattern = "/<([\w]+)([^>]*?)(([\s]*\/>)|(>((([^<]*?|<\!\-\-.*?\-\->)|(?R))*)<\/\\1[\s]*>))/s";
Sadece dene. Bir PHP dizgesi olarak yazılmıştır, bu yüzden "s" değiştiricisi sınıfların satırsonu içermesini sağlar.
İşte bu kılavuzu PHP üzerinde örnek notu Ocak ayında yazdım: Referans
(Dikkatli olun. Bu notta yanlış bir şekilde "m" değiştiricisini kullandım; normal ifade motoru tarafından atılmasına rağmen silinmesi gerekir, çünkü hiç ^
veya $
çapa kullanılmamıştı).
Şimdi, bu yöntemin sınırları hakkında daha bilinçli bir bakış açısıyla konuşabiliriz:
- düzenli ifade motorunun belirli uygulamasına göre, özyineleme, ayrıştırılan iç içe geçmiş örüntülerin sayısında bir sınıra sahip olabilir , ancak kullanılan dile bağlıdır
- bozuk olmasına rağmen, (x) HTML ciddi hatalara yol açmaz. Sterilize edilmemiştir .
Her neyse, bu yalnızca bir düzenli ifade kalıbıdır, ancak birçok güçlü uygulamanın geliştirilme olasılığını ortaya koymaktadır.
Bu modeli, çerçevemde oluşturduğum bir şablon motorunun özyinelemeli iniş ayrıştırıcısına güç vermek için yazdım ve performanslar hem yürütme zamanlarında hem de bellek kullanımında gerçekten harika (aynı sözdizimini kullanan diğer şablon motorlarıyla hiçbir ilgisi yok).
Pek çok kişinin daha önce de belirttiği gibi, HTML normal bir dil değildir ve bu da ayrıştırmayı çok zorlaştırabilir. Buna çözümüm, düzenli bir program kullanarak onu normal bir dile dönüştürmek ve ardından sonuçları tüketmek için bir XML ayrıştırıcı kullanmak. Bunun için birçok iyi seçenek var. Programım, HTML'yi XML'e ve ardından Jaxen'den xpath'e sonuca dönüştürmek için jtidy kitaplığı ile Java kullanılarak yazılmıştır .
<\s*(\w+)[^/>]*>
Parçaların açıklaması:
<
: Başlangıç karakteri
\s*
: Etiket adından önce boşluklar olabilir (çirkin, ancak mümkün).
(\w+)
: etiketler harf ve sayı (h1) içerebilir. Pekala, \w
'_' ile de eşleşiyor, ancak sanırım canımı yakmıyor. Merak ediyorsanız, bunun yerine ([a-zA-Z0-9] +) kullanın.
[^/>]*
: Kapanış dışında >
ve /
kapanana kadar her şey>
>
: Kapanış >
İLGİLİ OLMAYAN
Düzenli ifadeleri küçümseyen arkadaşlara, bunların yalnızca normal diller kadar güçlü olduklarını söyleyerek:
Bir n ba n ba n değil düzenli ve hatta bağlam serbest olan ile eşleştirilebilir^(a+)b\1b\1$
Geri referans FTW !
Yalnızca bu etiketleri bulmaya çalışıyorsanız (ayrıştırma tutkusu olmadan) şu normal ifadeyi deneyin:
/<[^/]*?>/g
30 saniyede yazdım ve burada test ettim: http://gskinner.com/RegExr/
Yok saymak istediğinizi söylediğiniz türleri yok sayarken, bahsettiğiniz etiket türleriyle eşleşir.
Bana öyle geliyor ki etiketleri sonunda "/" olmadan eşleştirmeye çalışıyorsunuz. Bunu dene:
<([a-zA-Z][a-zA-Z0-9]*)[^>]*(?<!/)>
HTML ile uğraşırken, özellikle de doğruluk çok önemliyse (örneğin, işleminizin güvenlik açısından etkileri varsa), programlama sırasında normal ifadeler yerine özel ayrıştırıcılar ve API'ler kullanmak en iyisidir. Bununla birlikte, XML tarzı işaretlemenin asla normal ifadelerle işlenmemesi gerektiğine dair dogmatik bir görüşe atfetmiyorum. Düzenli ifadelerin iş için harika bir araç olduğu durumlar vardır; örneğin, bir metin düzenleyicide bir defalık düzenlemeler yaparken, bozuk XML dosyalarını düzeltirken veya XML'e benzeyen ancak tam olarak XML olmayan dosya biçimleriyle uğraşırken. Farkında olunması gereken bazı sorunlar var, ancak bunlar aşılamaz ve hatta mutlaka alakalı değiller.
Benzeri basit bir normal ifade <([^>"']|"[^"]*"|'[^']*')*>
, az önce bahsettiğim gibi durumlarda genellikle yeterince iyidir. Her şey düşünüldüğünde saf bir çözümdür, ancak >
öznitelik değerlerinde kodlanmamış sembollere doğru bir şekilde izin verir . Örneğin bir table
etiket arıyorsanız, onu olarak uyarlayabilirsiniz </?table\b([^>"']|"[^"]*"|'[^']*')*>
.
Daha "gelişmiş" bir HTML normal ifadesinin neye benzeyeceğine dair bir fikir vermek için, aşağıdakiler gerçek dünyadaki tarayıcı davranışını ve HTML5 ayrıştırma algoritmasını taklit etme konusunda oldukça saygın bir iş çıkarmaktadır:
</?([A-Za-z][^\s>/]*)(?:=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)|[^>])*(?:>|$)
Aşağıdakiler, XML etiketlerinin oldukça katı bir tanımıyla eşleşir (XML adlarında izin verilen tüm Unicode karakterleri hesaba katılmasa da):
<(?:([_:A-Z][-.:\w]*)(?:\s+[_:A-Z][-.:\w]*\s*=\s*(?:"[^"]*"|'[^']*'))*\s*/?|/([_:A-Z][-.:\w]*)\s*)>
Kabul edilirse, bunlar çevreleyen bağlamı ve birkaç uç durumu hesaba katmaz, ancak gerçekten isterseniz bu tür şeyler bile halledilebilir (örneğin, başka bir normal ifadenin eşleşmeleri arasında arama yaparak).
Günün sonunda, bu aracın bir normal ifade olduğu durumlarda bile iş için en uygun aracı kullanın.
Bu amaçla düzenli ifadeler kullanmak uygun ve etkili olmasa da bazen normal ifadeler basit eşleşme problemleri için hızlı çözümler sağlar ve bence önemsiz işler için normal ifadeleri kullanmak o kadar da korkunç değildir.
Bir yoktur kesin blog yazısı Steven Levithan tarafından yazılmış en içteki HTML öğelerini eşleştirme hakkında.