2012-01-03 15 views
5

मैं अलग-अलग वैरिएबल में निम्नलिखित बैश के भीतर से रेगुलर एक्सप्रेशन का उपयोग करने के लिए इसी तरह के तार पार्स करने के लिए करना चाहते हैं: पहले "शीर्षक"वैकल्पिक पैरामीटर

Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title"; 

या

Category: resource;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Resource";rel="http://schemas.ogf.org/occi/core#entity";attributes="occi.core.summary"; 

पहले भाग सभी तारों के लिए आम है, भागों के शीर्षक और गुण वैकल्पिक हैं।

मैं सभी तारों के लिए सामान्य अनिवार्य पैरामीटर निकालने में कामयाब रहा, लेकिन मुझे वैकल्पिक पैरामीटर के साथ परेशानी है जो सभी तारों के लिए जरूरी नहीं है। जहां तक ​​मुझे पता चला, बैश गैर-कैप्चरिंग कोष्ठक का समर्थन नहीं करता है जिसका उपयोग मैं इस उद्देश्य के लिए करता हूं।

CATEGORY_REGEX='Category:\s*([^;]*);scheme="([^"]*)";class="([^"]*)";' 
category_string='Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title";' 
[[ $category_string =~ $CATEGORY_REGEX ]] 
echo ${BASH_REMATCH[0]} 
echo ${BASH_REMATCH[1]} 
echo ${BASH_REMATCH[2]} 
echo ${BASH_REMATCH[3]} 

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

CATEGORY_REGEX='Category:\s*([^;]*);\s*scheme="([^"]*)";\s*class="([^"]*)";\s*(?:title="([^"]*)";)?\s*(?:rel="([^"]*)";)?\s*(?:location="([^"]*)";)?\s*(?:attributes="([^"]*)";)?\s*(?:actions="([^"]*)";)?' 

वहाँ किसी भी है

यहाँ मैं अब तक क्या हासिल है पर्ल, पायथन या रूबी पर वापस गिरने के बिना कमांड लाइन टूल्स के साथ स्ट्रिंग को पार्स करने के लिए अन्य समाधान?

उत्तर

6

मैं गैर पर कब्जा समूहों बैश regex में मौजूद हैं, तो अपने विकल्पों को एक पटकथा भाषा का उपयोग करने के लिए या (?:...) समूह के सभी से ?: दूर करने के लिए और बस के बारे में जो समूहों आप संदर्भ सावधान रहना होगा, उदाहरण के लिए कर रहे हैं नहीं लगता है :

CATEGORY_REGEX='Category:\s*([^;]*);\s*scheme="([^"]*)";\s*class="([^"]*)";\s*(title="([^"]*)";)?\s*(rel="([^"]*)";)?\s*(location="([^"]*)";)?\s*(attributes="([^"]*)";)?\s*(actions="([^"]*)";)?' 
category_string='Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title";' 
[[ $category_string =~ $CATEGORY_REGEX ]] 
echo "full:  ${BASH_REMATCH[0]}" 
echo "category: ${BASH_REMATCH[1]}" 
echo "scheme:  ${BASH_REMATCH[2]}" 
echo "class:  ${BASH_REMATCH[3]}" 
echo "title:  ${BASH_REMATCH[5]}" 
echo "rel:  ${BASH_REMATCH[7]}" 
echo "location: ${BASH_REMATCH[9]}" 
echo "attributes: ${BASH_REMATCH[11]}" 
echo "actions: ${BASH_REMATCH[13]}" 

ध्यान दें कि वैकल्पिक पैरामीटर हम एक समूह हर बार छोड़ करने की आवश्यकता के साथ शुरू, क्योंकि पर 4 से भी गिने समूहों पैरामीटर नाम के साथ-साथ मान (यदि पैरामीटर मौजूद है)।

+0

वास्तव में यह काम कर रहा है। यह सबसे सुरुचिपूर्ण समाधान नहीं है, लेकिन जब तक बैश में कोई गैर-कैप्चरिंग समूह नहीं है, तब तक प्रत्येक समूह को छोड़ने के साथ कामकाज शायद सबसे अच्छा समाधान है। एक बात अभी भी मुझे परेशान करती है: यदि किसी भी अर्धविराम के पीछे रिक्त स्थान हैं, तो रेगेक्स विफल रहता है, इसलिए व्हाइटस्पेस से मेल खाने के लिए उनके पीछे "\ s *" पैटर्न हैं। –

+0

ऐसा लगता है कि "\ s *" जैसे विशेष वर्ण काम नहीं कर रहे हैं। इसे केवल एक स्थान के साथ बदलकर काम किया गया: "\ s *" => "*" –

+0

\ [: space:]] * के बजाय * का उपयोग करने का प्रयास करें। –

0

आप regexp जादू का एक छोटा सा का उपयोग कर बैश में गैर-मेल खाने वाले समूह का अनुकरण कर सकते हैं:

   _2__ _4__ _5__ 
[[ "[email protected]" =~ ((.+)@|)((.+)/|)(.+) ]]; 
echo "${BASH_REMATCH[2]:--} ${BASH_REMATCH[4]:--} ${BASH_REMATCH[5]:--}" 
# Output: fu - k 

वर्ण @ और / स्ट्रिंग के कुछ हिस्सों हम पार्स कर रहे हैं। Regexp पाइप | या तो बाएं या दाएं (खाली) भाग मिलान के लिए उपयोग किया जाता है।

उत्सुक के लिए, ${VAR:-<default value>} $ VAR खाली होने पर डिफ़ॉल्ट मान के साथ परिवर्तनीय विस्तार है।

+0

यह मेरे लिए काम नहीं करता है। मुझे बस तीन डैश मिलते हैं। – Joeytje50

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