2012-05-05 19 views
7

मेरा अनुभव मुझे बताता है कि one should not use RegExp to parse HTML/XML, और मैं पूरी तरह से सहमत हूं! यहडोम पार्सर्स कैसे कार्यान्वित किए जाते हैं?

  • गन्दा
  • मजबूत नहीं है और आसानी से टूट गया है
  • शुद्ध बुराई

वे सब कहते हैं कि किसी प्रकार का है, जो मेरे द्वारा ठीक है की "एक डोम पार्सर का उपयोग करें"। लेकिन अब मैं उत्सुक हो गया। वे कैसे काम करते हैं?

मैं DOMDocument क्लास स्रोत की खोज कर रहा था, और उसे नहीं मिला।

यह प्रश्न इस तथ्य से आता है कि filter_var() उदाहरण के लिए, RegExp के साथ ईमेल मान्य करने के लिए एक अच्छा विकल्प माना जाता है, लेकिन जब आप स्रोत को देखते हैं, तो आप देखेंगे कि यह वास्तव में RegExp का उपयोग करता है!

तो, यदि आप PHP में एक डोम पार्सर बनाना चाहते थे? आप HTML को पार्स करने के बारे में कैसे जाएंगे? उन्होंने यह कैसे किया?

+2

डोम पार्सर्स को आम तौर पर टोकननाइज़र के रूप में लागू किया जाता है। यदि आप सी # पढ़ सकते हैं, [एचटीएमएल एजिलिटी पैक] के लिए स्रोत कोड (http://htmlagilitypack.codeplex.com) दृष्टिकोण को स्पष्ट कर सकता है। – Oded

+4

'filter_var()' के बारे में: किसी ने कभी भी नहीं कहा है कि आपको regex के साथ एक ईमेल पता मान्य नहीं करना चाहिए। तथ्य यह है कि, इस कार्य के लिए एक रेगेक्स लिखना * सही * बहुत मुश्किल है और इसके लिए बहुत सारे शोध प्रयास की आवश्यकता है। तो वहां हजारों भयानक कार्यान्वयन हैं। यही कारण है कि आपको बस 'filter_var() 'का उपयोग करना चाहिए। – kapa

+0

यदि आप एक्सएचटीएमएल से निपट रहे हैं, तो एक सामान्य एक्सएमएल पार्सर ठीक काम करेगा। – Niko

उत्तर

5

मुझे लगता है कि आपको लेख How Browsers Work: Behind the Scenes of Modern Web Browsers देखना चाहिए। यह एक लंबा पठन है, लेकिन आपके समय के लायक है। विशेष रूप से, एचटीएमएल पार्सर सेक्शन।

जबकि मैं लेख न्याय नहीं कर सकता, शायद एक सरसरी सारांश एक को पकड़ने के लिए अच्छा होगा जब तक कि उस कृति को पढ़ने और पचाने का समय न हो। हालांकि मुझे यह स्वीकार करना होगा कि इस क्षेत्र में मैं बहुत कम अनुभव वाला नौसिखिया हूं। लगभग 10 वर्षों तक पेशेवर रूप से वेब के लिए विकसित होने के बाद, जिस तरीके से ब्राउज़र मेरे कोड को संभालता है और उसका अर्थ देता है, वह एक काला बॉक्स रहा है।

एचटीएमएल, एक्सएचटीएमएल, सीएसएस या जावास्क्रिप्ट - अपना चयन लें। वे सभी एक व्याकरण, साथ ही एक शब्दावली है। अंग्रेजी एक और महान उदाहरण है। हमारे पास व्याकरणिक नियम हैं जिन्हें हम लोगों, पुस्तकों और अधिक का पालन करने की उम्मीद करते हैं। हमारे पास संज्ञाएं, क्रियाएं, विशेषण आदि से बना शब्दावली भी है।

ब्राउज़र अपने व्याकरण की जांच करके, साथ ही इसकी शब्दावली की जांच करके दस्तावेज़ की व्याख्या करते हैं। जब यह वस्तुओं में आता है तो अंत में यह समझ में नहीं आता है, यह आपको बताएगा (अपवाद उठा रहा है, आदि)। आप और मैं आम बात करते हैं।

मैं StackOverflow प्यार करता हूँ, लेकिन अगर मैं कैसे आप तुरंत शब्द और शब्दों के बीच संबंधों के अलावा लेने के लिए शुरू ऊपर के उदाहरण में एक बात यह absolutamente जा टूट किया जाएगा ...

नोट बदल सकता है । शुरुआत पूरी समझ में आता है, "मुझे स्टैक ओवरफ्लो पसंद है।" फिर हम "... अगर मैं बदल सकता था," और हम तुरंत बंद हो जाते हैं। "बदला" यहां से संबंधित नहीं है। इसकी संभावना है कि लेखक के बजाय "परिवर्तन" का अर्थ है।अब शब्दावली सही है, लेकिन व्याकरण गलत है। थोड़ी देर बाद हम "हो" में आते हैं जो व्याकरणिक शासन का उल्लंघन भी कर सकता है, और थोड़ी और आगे हम "absolutamentamente" शब्द का सामना करते हैं, जो अंग्रेजी शब्दावली का हिस्सा नहीं है - एक और गलती। एक DOCTYPE के मामले में यह सब के

Think। मैंने अभी एक्सएचटीएमएल 1.0 सख्त डॉक्टरेट के पीछे स्रोत की दूसरी मॉनिटर पर खोला है। इसके आंतरिक में निम्नलिखित हैं:

<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> 

यह शीर्षक इकाइयों को परिभाषित करता है। और जब तक मैं एक्सएचटीएमएल के व्याकरण का पालन करता हूं, मैं अपने दस्तावेज़ में इनमें से किसी एक का उपयोग कर सकता हूं (<h1>Hello World</h1>)। लेकिन अगर मैं एक बनाने के लिए प्रयास करते हैं, H7 कहते हैं, ब्राउज़र के रूप में शब्दावली से अधिक ठोकर होगा "विदेशी" और सूचित मुझे:

"लाइन 7, स्तंभ 8: तत्व" H7 "अनिर्धारित"

शायद जबकि दस्तावेज़ को पार्स हम भर में <table आते हैं। हम जानते हैं कि अब हम एक table तत्व है, जो जब तक हम भाषा, व्याकरण के नियमों, आदि के रूप में जानते हैं शब्दावली जैसे tbody, tr, आदि के अपने स्वयं के सेट है साथ काम कर रहे, हम जानते हैं कि कुछ गलत है जब। XHTML 1.0 स्ट्रिक्ट Doctype में लौटने के बाद हम निम्न को खोजें:

<!ELEMENT table 
    (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> 
<!ELEMENT caption %Inline;> 
<!ELEMENT thead (tr)+> 
<!ELEMENT tfoot (tr)+> 
<!ELEMENT tbody (tr)+> 
<!ELEMENT colgroup (col)*> 
<!ELEMENT col  EMPTY> 
<!ELEMENT tr  (th|td)+> 
<!ELEMENT th  %Flow;> 
<!ELEMENT td  %Flow;> 

इस संदर्भ को देखते हुए, हम जो कुछ भी स्रोत हम पार्स करने कर रहे हैं के खिलाफ चल रहे एक जांच रख सकते हैं। अगर लेखक tread लिखते हैं, तो thead के बजाय, हमारे पास एक मानक है जिसके द्वारा हम यह निर्धारित कर सकते हैं कि त्रुटि में होना है। जब समस्याएं अनसुलझे होती हैं, और हम व्याकरण और शब्दावली के कुछ उपयोगों से मेल खाने के लिए नियम नहीं पा रहे हैं, तो हम लेखक को सूचित करते हैं कि उनका दस्तावेज़ अमान्य है।

मैं इस विज्ञान न्याय का कोई मतलब नहीं कर रहा हूं, हालांकि मुझे उम्मीद है कि यह सेवा करता है - यदि कुछ और नहीं - पर्याप्त होने के लिए आप इसे बैठकर अपने उत्तर में इस लेख की शुरुआत के रूप में संदर्भित लेख को पढ़ सकते हैं, और शायद बैठकर विभिन्न डीटीडी का अध्ययन करें जिन्हें हम दिन-प्रतिदिन सामना करते हैं।

1

अच्छी खबर यहां है, आपको पहिया को फिर से शुरू करने की आवश्यकता नहीं है। libxml library का उपयोग PHP के DOMDocument एक्सटेंशन के भीतर किया जाता है और इसका स्रोत कोड उपलब्ध है। Have a look there मेरा सुझाव है।

और बीटीडब्लू।, नियमित अभिव्यक्ति हमेशा गलत नहीं होती है, लेकिन आपको सीधे उन लोगों का उपयोग करने की ज़रूरत है जो आप सीधे हेल्स रसोई में जाते हैं, एक किट्टी धारावाहिक हत्यारा बन जाते हैं या चुतुल्लू जाते हैं या उस आदमी को कैसे बुलाया जाता है। मैं निम्नलिखित पढ़ने के लिए सुझाव देता हूं: REX: XML Shallow Parsing with Regular Expressions

लेकिन यदि आप सबकुछ सही करते हैं, तो नियमित अभिव्यक्ति आपको पार्सिंग के साथ बहुत मदद कर सकती हैं। यह सिर्फ आपको पता होना चाहिए कि आप क्या करते हैं।

+0

जैसा कि मैंने कहा है, मैं पहिया को फिर से शुरू करने की कोशिश नहीं कर रहा हूं, मैं सिर्फ चक्र पर काम करने के बारे में उत्सुक हूं। इसके अलावा मैंने DOMDocument के स्रोत को खोजने का प्रयास किया और इसे नहीं मिला। –

+0

मैंने libxml के स्रोत को लिंक किया। अपनी वेबसाइट पर आर्किटेक्चर का वर्णन भी देखें, परियोजना काफी बड़ी है। और साथ ही htmlpurifier प्रोजेक्ट भी है जो एक PHP पार्सर है जो PHP IIRC में लिखा गया है। – hakre

संबंधित मुद्दे