2009-03-31 10 views
5

क्या यह इंगित करने का कोई तरीका है कि किसी भी क्रम में दो या दो से अधिक रेगेक्स वाक्यांश हो सकते हैं? उदाहरण के लिए, एक्सएमएल विशेषताओं को किसी भी क्रम में लिखा जा सकता है। कि मैं निम्न XML है कहते हैं:परिवर्तनीय ऑर्डर रेगेक्स सिंटैक्स

<a href="home.php" class="link" title="Home">Home</a> 
<a href="home.php" title="Home" class="link">Home</a> 

मैं एक मैच है कि वर्ग और शीर्षक की जाँच करता है और दोनों ही मामलों के लिए काम करता है कैसे लिख होगा? मैं मुख्य रूप से वाक्यविन्यास की तलाश में हूं जो मुझे किसी भी क्रम में जांचने की अनुमति देता है, न केवल कक्षा और शीर्षक से मेल खाता है क्योंकि मैं ऐसा कर सकता हूं। क्या दोनों संयोजनों और उन्हें '|' से जोड़ने के अलावा कोई रास्ता है?

संपादित: मेरी प्राथमिकता एक भी regex में यह करने के लिए के रूप में मैं यह प्रोग्राम के परीक्षण के निर्माण कर रहा हूँ और यह भी इकाई होगी।

+0

मुझे @ जोश बुश का जवाब बहुत नीचे है जैसा कि अब मेरे लिए काम कर रहा है कि मैं इस – Rick

+0

पर आया, नहीं, आप इसे नहीं कर सकते। यही कारण है कि आप ** HTML (या XML) को पार्स करने के लिए नियमित अभिव्यक्तियों का उपयोग नहीं करते हैं। एक उचित एचटीएमएल पार्सिंग मॉड्यूल का प्रयोग करें। ** आप विश्वसनीय अभिव्यक्तियों के साथ एचटीएमएल को विश्वसनीय रूप से पार्स नहीं कर सकते हैं, और आपको सड़क के नीचे दुःख और निराशा का सामना करना पड़ेगा। जैसे ही आपकी अपेक्षाओं से HTML बदल जाता है, आपका कोड टूटा जाएगा। Http: // htmlparsing देखें।PHP मॉड्यूल के साथ HTML को सही तरीके से पार्स करने के उदाहरणों के उदाहरण के लिए com/php जो पहले से ही लिखे गए, परीक्षण और डिबग किए गए हैं। –

+0

यह कई कारणों में से एक है रेगेक्स एक्सएमएल या एचटीएमएल को पार्स करने के लिए उपयुक्त नहीं हैं। –

उत्तर

8

नहीं, मुझे विश्वास है कि एक ही आरई के साथ ऐसा करने का सबसे अच्छा तरीका बिल्कुल वर्णन है जैसा आप वर्णन करते हैं। दुर्भाग्यवश, यह बहुत गन्दा हो जाएगा जब आपके एक्सएमएल में 5 अलग-अलग गुण हो सकते हैं, जिससे आपको बड़ी विभिन्न आरईएस की जांच करने के लिए दिया जा सकता है।

दूसरी तरफ, मैं इसे आरई के साथ नहीं करूँगा क्योंकि वे प्रोग्रामिंग भाषा होने के लिए नहीं हैं। एक्सएमएल प्रोसेसिंग लाइब्रेरी का उपयोग करने के पुराने तरीके से क्या गलत है?

यदि आप आरई का उपयोग करने के लिए आवश्यक हैं, तो यह उत्तर शायद अधिक सहायता नहीं करेगा, लेकिन मुझे नौकरी के लिए सही टूल का उपयोग करने में विश्वास है।

+2

अधिकांश HTML मान्य XML नहीं है। तो आपको वास्तव में एक HTML पार्सिंग लाइब्रेरी की आवश्यकता होगी। और इस जानकारी के आधार पर आप इस जानकारी को खींचने की कोशिश क्यों कर रहे हैं, यह कुछ लाइब्रेरी के आसपास एक एप्लिकेशन लिखने की गारंटी नहीं दे सकता है। शायद यह सिर्फ एक चीज है जहां आप कुछ मोटा जानकारी प्राप्त करना चाहते हैं। दुर्भाग्यवश, – Kibbee

+0

दुर्भाग्यवश, मुझे लगता है कि मुझे एक हास्यास्पद संख्या में क्रमिक क्रम के विरुद्ध गैर-मान्य XML को पार्स करने में सक्षम होने के मूल्य का वजन करना होगा। एक निश्चित बिंदु पर, रेगेक्स छोटा नहीं होगा। यह सिर्फ एक ऑफ-ऑफ प्रोजेक्ट नहीं है, लेकिन मुझे लगता है कि मुझे लाइब्रेरी का उपयोग करना होगा। – VirtuosiMedia

+1

कुछ regexes एक भयानक विचार नहीं हो सकता है, लेकिन यह सब कुछ एक में सब कुछ नहीं करना सबसे अच्छा है। सबसे पहले, के अंदर सामान प्राप्त करने के लिए एक रेगेक्स का उपयोग करें, फिर तत्वों को निकालने के लिए दूसरे का उपयोग करें, और उन्हें तदनुसार संसाधित करें। यह बहुत अधिक पठनीय और लिखना आसान है। –

0

सबसे अच्छा तरीका एक रेगेक्स लिखना होगा जो <a .... > भाग उठाता है, और फिर कक्षा और शीर्षक को खींचने के लिए दो और regexes लिखें। यद्यपि आप शायद इसे एक रेगेक्स के साथ कर सकते हैं, यह बहुत जटिल होगा, और संभवतः बहुत अधिक त्रुटि प्रवण होगी।

एक भी रेगुलर एक्सप्रेशन से आप की तरह

<a[^>]*((class="([^"]*)")|(title="([^"]*)"))?((title="([^"]*)")|(class="([^"]*)"))?[^>]*> 

कुछ कौन करता है, तो यह और भी मान्य है देखने के लिए जाँच के बिना सिर्फ एक पहले हाथ अनुमान है की आवश्यकता होगी के साथ

। बस विभाजन और समस्या को जीतने के लिए बहुत आसान है।

+0

सभी क्रमपरिवर्तनों का आकलन करना संभव हो सकता है, तीन विशेषताओं के लिए हो सकता है, लेकिन क्योंकि क्रमपरिवर्तन की संख्या घातीय बढ़ जाती है, यह समाधान बहुत बड़ी समस्या बन जाता है। –

0

पहला विज्ञापन समाधान निम्न कार्य करने के लिए हो सकता है।

((class|title)="[^"]*?" *)+ 

यह बिल्कुल सही नहीं है क्योंकि यह प्रत्येक विशेषता को एक से अधिक बार होने की अनुमति देता है। मैं कल्पना कर सकता हूं कि यह दावा के साथ हल किया जा सकता है। लेकिन अगर आप केवल विशेषताओं को निकालना चाहते हैं तो यह पहले से ही पर्याप्त हो सकता है।

2

आप टैग के गुणों को खींचने के लिए नामित समूहों का उपयोग कर सकते हैं। रेगेक्स चलाएं और फिर समूह पर लूप करें जो आपको चाहिए।

कुछ इस तरह (अपरीक्षित, \ शब्द अक्षर और \ रों खाली स्थान के लिए के लिए डब्ल्यू के साथ .net regex सिंटैक्स का उपयोग):

<a ((?<key>\w+)\s?=\s?['"](?<value>\w+)['"])+ /> 
+0

यह शायद सबसे समझदार समाधान है, केवल रेगेक्स (प्री-बिल्ट सीएसएस पार्सर के बजाय) – Rick

-1

आप तत्वों का एक सेट का क्रमपरिवर्तन का मिलान करना चाहते हैं, तो आप बैक रेफरेंस और शून्य-चौड़ाई नकारात्मक अग्रेषण मिलान के संयोजन का उपयोग कर सकते हैं।

123-abc-456-def-789-ghi-0AB 
123-abc-456-ghi-789-def-0AB 
123-def-456-abc-789-ghi-0AB 
123-def-456-ghi-789-abc-0AB 
123-ghi-456-abc-789-def-0AB 
123-ghi-456-def-789-abc-0AB 

आप निम्न regex के साथ ऐसा कर सकते हैं::

/123-(abc|def|ghi)-456-(?!\1)(abc|def|ghi)-789-(?!\1|\2)(abc|def|ghi)-0AB/ 

वापस संदर्भ (\1, \2), तो आपको जाने

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

तो, उदाहरण के लिए, माणिक में:

input = <<LINES 
123-abc-456-abc-789-abc-0AB 
123-abc-456-abc-789-def-0AB 
123-abc-456-abc-789-ghi-0AB 
123-abc-456-def-789-abc-0AB 
123-abc-456-def-789-def-0AB 
123-abc-456-def-789-ghi-0AB 
123-abc-456-ghi-789-abc-0AB 
123-abc-456-ghi-789-def-0AB 
123-abc-456-ghi-789-ghi-0AB 
123-def-456-abc-789-abc-0AB 
123-def-456-abc-789-def-0AB 
123-def-456-abc-789-ghi-0AB 
123-def-456-def-789-abc-0AB 
123-def-456-def-789-def-0AB 
123-def-456-def-789-ghi-0AB 
123-def-456-ghi-789-abc-0AB 
123-def-456-ghi-789-def-0AB 
123-def-456-ghi-789-ghi-0AB 
123-ghi-456-abc-789-abc-0AB 
123-ghi-456-abc-789-def-0AB 
123-ghi-456-abc-789-ghi-0AB 
123-ghi-456-def-789-abc-0AB 
123-ghi-456-def-789-def-0AB 
123-ghi-456-def-789-ghi-0AB 
123-ghi-456-ghi-789-abc-0AB 
123-ghi-456-ghi-789-def-0AB 
123-ghi-456-ghi-789-ghi-0AB 
LINES 

# outputs only the permutations 
puts input.grep(/123-(abc|def|ghi)-456-(?!\1)(abc|def|ghi)-789-(?!\1|\2)(abc|def|ghi)-0AB/) 

पांच तत्वों का क्रमपरिवर्तन के लिए, यह होगा:

/1-(abc|def|ghi|jkl|mno)- 
2-(?!\1)(abc|def|ghi|jkl|mno)- 
3-(?!\1|\2)(abc|def|ghi|jkl|mno)- 
4-(?!\1|\2|\3)(abc|def|ghi|jkl|mno)- 
5-(?!\1|\2|\3|\4)(abc|def|ghi|jkl|mno)-6/x 

अपने उदाहरण के लिए, regex होगा

/<a href="home.php" (class="link"|title="Home") (?!\1)(class="link"|title="Home")>Home<\/a>/ 
3

आप प्रत्येक विशेषता के लिए एक लुकहेड बना सकते हैं और पूरे टैग के लिए उन्हें रेगेक्स में प्लग कर सकते हैं। उदाहरण के लिए, टैग के लिए रेगुलर एक्सप्रेशन से आप XML पर इस प्रयोग कर रहे हैं तो आप शायद अधिक व्यापक कुछ की आवश्यकता होगी

<a\b[^<>]*> 

हो सकता है। अपने आप में, यह बेस रेगेक्स शून्य या अधिक विशेषताओं वाले टैग से मेल खाएगा। तो आपके द्वारा चयनित विशेषताओं से मिलान करना चाहते से प्रत्येक के लिए एक lookhead जोड़ें:

(?=[^<>]*\s+class="link") 
(?=[^<>]*\s+title="Home") 

[^<>]* यह विशेषता के लिए आगे स्कैन की सुविधा देता है, लेकिन यह समापन कोण कोष्ठक परे देखने नहीं दूँगा। लुकहेड में अग्रणी व्हाइटस्पेस से मिलान करना दो उद्देश्यों को पूरा करता है: बेस रेगेक्स में इसे मिलान करने से अधिक लचीला है, और यह सुनिश्चित करता है कि हम एक संपूर्ण विशेषता नाम से मेल खाते हैं। उन्हें मिलाकर हम पाते हैं:

<a\b(?=[^<>]*\s+class="link")(?=[^<>]*\s+title="Home")[^<>]+>[^<>]+</a> 

बेशक, मैंने स्पष्टता के लिए कुछ सरल धारणाएं की हैं। मैंने बराबर संकेतों के चारों ओर सफेद जगहों की अनुमति नहीं दी, एकल-उद्धरण या विशेषता मानों के चारों ओर कोई उद्धरण नहीं, या विशेषता मानों में कोण ब्रैकेट के लिए (जो मैंने सुना है कानूनी है, लेकिन मैंने इसे कभी नहीं देखा है)। उन रिसावों को प्लग करना (यदि आपको आवश्यकता है) regex uglier बना देगा, लेकिन बुनियादी संरचना में परिवर्तन की आवश्यकता नहीं होगी।

5

क्या आपने xpath माना है? (जहां विशेषता क्रम आवश्यक नहीं है)

//a[@class and @title] 

वैध मेल के रूप में दोनों <a> नोड्स का चयन करेंगे। एकमात्र चेतावनी यह है कि इनपुट xhtml होना चाहिए (अच्छी तरह से बनाया गया एक्सएमएल)।

+0

मैं अब थोड़ा सा एक्सपैथ का उपयोग कर रहा हूं, अच्छा सुझाव। – VirtuosiMedia

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