html - क्या आप कुछ उदाहरण प्रदान कर सकते हैं कि रेगेक्स के साथ एक्सएमएल और एचटीएमएल का विश्लेषण करना मुश्किल क्यों है?




xml regex (8)

एक गलती है कि मैं लोगों को बार-बार बार-बार देख रहा हूं कि वे रेगेक्स के साथ एक्सएमएल या एचटीएमएल को पार्स करने का प्रयास कर रहे हैं। XML और HTML को पार्स करने के कुछ कारण यहां दिए गए हैं:

लोग लाइनों के अनुक्रम के रूप में फ़ाइल का इलाज करना चाहते हैं, लेकिन यह मान्य है:

<tag
attr="5"
/>

लोग टैग की शुरुआत के रूप में <या <टैग का इलाज करना चाहते हैं, लेकिन इस तरह की चीजें जंगली में मौजूद हैं:

<img src="imgtag.gif" alt="<img>" />

लोग अक्सर टैग को समाप्त करने के लिए टैग शुरू करना चाहते हैं, लेकिन एक्सएमएल और एचटीएमएल टैग को स्वयं को शामिल करने की अनुमति देता है (जो परंपरागत regexes बिल्कुल संभाल नहीं सकते हैं):

<span id="outer"><span id="inner">foo</span></span> 

लोग अक्सर किसी दस्तावेज़ की सामग्री (जैसे प्रसिद्ध "किसी दिए गए पृष्ठ पर सभी फ़ोन नंबर ढूंढें) के खिलाफ मिलान करना चाहते हैं, लेकिन डेटा को चिह्नित किया जा सकता है (भले ही यह देखा जाने पर सामान्य प्रतीत होता है):

<span class="phonenum">(<span class="area code">703</span>)
<span class="prefix">348</span>-<span class="linenum">3020</span></span>

टिप्पणियों में खराब रूप से स्वरूपित या अपूर्ण टैग हो सकते हैं:

<a href="foo">foo</a>
<!-- FIXME:
    <a href="
-->
<a href="bar">bar</a>

आप किस अन्य गठिया के बारे में जानते हैं?


आम तौर पर, एक्सएमएल व्याकरण नियमित रूप से नियमित रूप से नहीं होने के कारण एक्सएमएल को रेगेक्स का उपयोग करके पार्स नहीं किया जा सकता है। इसे आसानी से रखने के लिए, regexes गिनती नहीं कर सकते हैं (ठीक है, पर्ल regexes वास्तव में चीजों की गिनती करने में सक्षम हो सकता है) ताकि आप खुले बंद टैग संतुलन नहीं कर सकते हैं।

मैं असहमत हूं। यदि आप रेगेक्स में रिकर्सिव का उपयोग करेंगे, तो आप आसानी से खुले और करीबी टैग ढूंढ सकते हैं।

Here मैंने पहले संदेश में उदाहरणों की पार्सिंग त्रुटियों से बचने के लिए रेगेक्स का उदाहरण दिखाया।


आपकी सूची में कोई गॉचा नहीं है कि विशेषता किसी भी क्रम में दिखाई दे सकती है, इसलिए यदि आपका रेगेक्स href "foo" और क्लास "बार" के साथ एक लिंक ढूंढ रहा है, तो वे किसी भी क्रम में आ सकते हैं, और किसी अन्य नंबर पर उनके बीच चीजें।


क्या लोग वास्तव में रेगेक्स का उपयोग कर गलती कर रहे हैं, या क्या यह उस कार्य के लिए पर्याप्त है जो वे हासिल करने की कोशिश कर रहे हैं?

मैं पूरी तरह से सहमत हूं कि रेगेक्स का उपयोग करके एचटीएमएल और एक्सएमएल को पार्स करना संभव नहीं है क्योंकि अन्य लोगों ने जवाब दिया है।

हालांकि, अगर आपकी आवश्यकता एचटीएमएल / एक्सएमएल को पार्स नहीं करना है, लेकिन एचटीएमएल / एक्सएमएल के "ज्ञात अच्छे" बिट में केवल एक छोटा सा डेटा प्राप्त करने के लिए हो सकता है तो शायद एक नियमित अभिव्यक्ति या यहां तक ​​कि एक सरल "सबस्ट्रिंग" भी पर्याप्त है।


मुझे लगता है कि समस्याएं उबालती हैं:

  1. रेगेक्स लगभग हमेशा गलत है। वैध इनपुट हैं जो सही तरीके से मिलान करने में असफल हो जाएंगे। यदि आप काफी मेहनत करते हैं तो आप इसे 99% सही, या 99.9 99% बना सकते हैं, लेकिन इसे 100% सही बनाना लगभग असंभव है, अगर केवल अजीब चीज़ों के कारण जो एक्सएमएल इकाइयों का उपयोग करके अनुमति देता है।

  2. यदि regex गलत है, यहां तक ​​कि 0.00001% इनपुट के लिए, तो आपके पास सुरक्षा समस्या है, क्योंकि कोई व्यक्ति आपके इनपुट को तोड़ने वाला एक इनपुट खोज सकता है।

  3. यदि रेगेक्स 99.99% मामलों को कवर करने के लिए पर्याप्त सही है तो यह पूरी तरह से अपठनीय और अनजान होने जा रहा है।

  4. यह बहुत संभावना है कि एक रेगेक्स मध्यम आकार की इनपुट फ़ाइलों पर बहुत बुरी तरह प्रदर्शन करेगा। एक्सएमएल के साथ मेरा पहला मुठभेड़ एक पर्ल स्क्रिप्ट को प्रतिस्थापित करना था (गलत तरीके से) एक उचित एक्सएमएल पार्सर के साथ आने वाले एक्सएमएल दस्तावेज़ों को पार्स किया गया था, और हमने न केवल 100 लाइनों के साथ अपठनीय कोड की 300 लाइनों को प्रतिस्थापित किया है, जिसे कोई भी समझ सकता है, लेकिन हमने उपयोगकर्ता प्रतिक्रिया समय में सुधार किया 10 सेकंड से लगभग 0.1 सेकंड तक।


मैं कहने का लुत्फ उठा रहा हूं "पहिया का पुन: आविष्कार न करें"। सिवाय इसके कि एक्सएमएल वास्तव में, वास्तव में जटिल प्रारूप है। तो शायद मुझे कहना चाहिए "synchrotron reinvent मत करो।"

शायद सही क्लिच शुरू होता है "जब आपके पास सब कुछ है हथौड़ा है ..." आप जानते हैं कि नियमित अभिव्यक्तियों का उपयोग कैसे करें, नियमित अभिव्यक्ति पार्सिंग में अच्छी होती है, तो एक्सएमएल पार्सिंग लाइब्रेरी सीखने के लिए परेशान क्यों?

क्योंकि एक्सएमएल पार्सिंग मुश्किल है । एक्सएमएल पार्सिंग लाइब्रेरी का उपयोग नहीं करना सीखकर आप जो भी प्रयास बचाते हैं, वह रचनात्मक काम और बग-स्विटिंग की मात्रा से अधिक होगा जो आपको करना होगा। अपने स्वयं के लिए, Google "एक्सएमएल लाइब्रेरी" और किसी और के काम का लाभ उठाएं।


मैंने here इस समस्या here एक सरल उत्तर here । हालांकि यह 100% अंक के लिए जिम्मेदार नहीं है, मैं समझाता हूं कि यदि आप कुछ प्री-प्रोसेसिंग कार्य करने के इच्छुक हैं तो यह कैसे संभव है।


यह "पार्सिंग" से आपका क्या मतलब है इस पर निर्भर करता है। आम तौर पर, एक्सएमएल व्याकरण नियमित रूप से नियमित रूप से नहीं होने के कारण एक्सएमएल को रेगेक्स का उपयोग करके पार्स नहीं किया जा सकता है। इसे आसानी से रखने के लिए, regexes गिनती नहीं कर सकते हैं (ठीक है, पर्ल regexes वास्तव में चीजों की गिनती करने में सक्षम हो सकता है) ताकि आप खुले बंद टैग संतुलन नहीं कर सकते हैं।


यहां आपके लिए कुछ मजेदार वैध एक्सएमएल है:

<!DOCTYPE x [ <!ENTITY y "a]>b"> ]>
<x>
    <a b="&y;>" />
    <![CDATA[[a>b <a>b <a]]>
    <?x <a> <!-- <b> ?> c --> d
</x>

और खुशी का यह छोटा बंडल वैध HTML है:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" [
    <!ENTITY % e "href='hello'">
    <!ENTITY e "<a %e;>">
]>
    <title>x</TITLE>
</head>
    <p id  =  a:b center>
    <span / hello </span>
    &amp<br left>
    <!---- >t<!---> < -->
    &e link </a>
</body>

अवैध संरचनाओं के लिए सभी ब्राउज़र-विशिष्ट पार्सिंग का उल्लेख नहीं करना है।

उस के खिलाफ शुभकामनाएं रीजिक्स!

संपादित करें (जोर्ग डब्ल्यू मिट्टाग): यहां अच्छी तरह से गठित, वैध HTML 4.01 का एक और अच्छा टुकड़ा है:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd"> 
<HTML/
  <HEAD/
    <TITLE/>/
    <P/>




regex