2009-06-17 13 views
6

सबसे अच्छा तरीका है हास्केलकेस-संवेदी नियमित अभिव्यक्ति

में विकल्प (झंडे) के साथ नियमित अभिव्यक्ति का उपयोग करने के क्या मैं का उपयोग

Text.Regex.PCRE 

प्रलेखन सूचीबद्ध करता compCaseless, compUTF8 जैसे कुछ दिलचस्प विकल्प, .. । लेकिन मैं कैसे साथ (= ~)

उत्तर

16

सभी Text.Regex.* मॉड्यूल जो कर रहे हैं typeclasses का भारी इस्तेमाल करते हैं, वहां विस्तारशीलता और "ओवरलोडिंग" के समान व्यवहार के लिए, लेकिन उपयोग कम obvio बनाते हैं हमें सिर्फ प्रकार देखने से।

अब, आप शायद मूल =~ मैचर से शुरू कर चुके हैं।

(=~) :: 
    (RegexMaker Regex CompOption ExecOption source 
    , RegexContext Regex source1 target) 
    => source1 -> source -> target 
(=~~) :: 
    (RegexMaker Regex CompOption ExecOption source 
    , RegexContext Regex source1 target, Monad m) 
    => source1 -> source -> m target 

=~ उपयोग करने के लिए, वहाँ एलएचएस के लिए RegexMaker ... का एक उदाहरण मौजूद होना चाहिए, और आरएचएस और परिणाम के लिए RegexContext ...

class RegexOptions regex compOpt execOpt | ... 
     | regex -> compOpt execOpt 
     , compOpt -> regex execOpt 
     , execOpt -> regex compOpt 
class RegexOptions regex compOpt execOpt 
     => RegexMaker regex compOpt execOpt source 
     | regex -> compOpt execOpt 
     , compOpt -> regex execOpt 
     , execOpt -> regex compOpt 
    where 
    makeRegex :: source -> regex 
    makeRegexOpts :: compOpt -> execOpt -> source -> regex 

इन सभी वर्गों के एक वैध उदाहरण (उदाहरण, regex=Regex, compOpt=CompOption, execOpt=ExecOption, और source=String के लिए) यह किसी न किसी रूप source से एक regexcompOpt,execOpt साथ विकल्पों को संकलित करने के संभव है का मतलब है। (इसके अलावा, कुछ regex प्रकार दिया, वहाँ ठीक एक compOpt,execOpt सेट है कि यह के साथ चला जाता है। विभिन्न source प्रकार के बहुत सारे ठीक है, हालांकि कर रहे हैं।)

class Extract source 
class Extract source 
     => RegexLike regex source 
class RegexLike regex source 
     => RegexContext regex source target 
    where 
    match :: regex -> source -> target 
    matchM :: Monad m => regex -> source -> m target 

इन सभी वर्गों के एक वैध उदाहरण (उदाहरण के लिए, regex=Regex , source=String, target=Bool) का अर्थ है और से target उत्पन्न करने के लिए मिलान करना संभव है। (अन्य वैध target रों दिया इन विशिष्ट regex और sourceInt, MatchResult String, MatchArray, आदि कर रहे हैं)

इन एक साथ रखो और यह बहुत स्पष्ट है कि =~ और =~~ बस कर रहे हैं सुविधा कार्यों

source1 =~ source 
    = match (makeRegex source) source1 
source1 =~~ source 
    = matchM (makeRegex source) source1 

है और यह भी कि =~ और =~~makeRegexOpts पर विभिन्न विकल्पों को पारित करने के लिए कोई कमरा नहीं छोड़ें।

आप बना सकते हैं अपने खुद के

(=~+) :: 
    (RegexMaker regex compOpt execOpt source 
    , RegexContext regex source1 target) 
    => source1 -> (source, compOpt, execOpt) -> target 
source1 =~+ (source, compOpt, execOpt) 
    = match (makeRegexOpts compOpt execOpt source) source1 
(=~~+) :: 
    (RegexMaker regex compOpt execOpt source 
    , RegexContext regex source1 target, Monad m) 
    => source1 -> (source, compOpt, execOpt) -> m target 
source1 =~~+ (source, compOpt, execOpt) 
    = matchM (makeRegexOpts compOpt execOpt source) source1 

जो तरीकों के साथ

"string" =~+ ("regex", CompCaseless + compUTF8, execBlank) :: Bool 

या =~ के ऊपर लिख और =~~ की तरह इस्तेमाल किया जा सकता

import Text.Regex.PCRE hiding ((=~), (=~~)) 

class RegexSourceLike regex source 
    where 
    makeRegexWith source :: source -> regex 
instance RegexMaker regex compOpt execOpt source 
     => RegexSourceLike regex source 
    where 
    makeRegexWith = makeRegex 
instance RegexMaker regex compOpt execOpt source 
     => RegexSourceLike regex (source, compOpt, execOpt) 
    where 
    makeRegexWith (source, compOpt, execOpt) 
     = makeRegexOpts compOpt execOpt source 

source1 =~ source 
    = match (makeRegexWith source) source1 
source1 =~~ source 
    = matchM (makeRegexWith source) source1 

विकल्पों को स्वीकार या तुम सिर्फ कर सकता कर सकते हैं जो match,का उपयोग करें, आदि जहां सीधे जरूरत है।

+0

आह, ऐसा लगता है कि मुझे समाधान में हराया गया है। मुझे अनावश्यक सामानों के सभी प्रकार लिखने के लिए यही मिलता है: -/ – ephemient

+0

आह, अब मुझे थोड़ा दोषी लगता है, आपका निश्चित रूप से एक अधिक व्यापक अवलोकन प्रदान करता है! मुझे आपको रास्ते में (= ~ +) के लिए सुझाव पसंद है। – dukedave

+0

यह वास्तव में एक बहुत ही पूर्ण और व्यापक उत्तर है, मैं प्रयास को पुरस्कृत करना चाहता हूं, लेकिन मुझे नहीं पता कि "स्वीकृत उत्तर" को स्विच करना आम बात है या नहीं? वैसे भी, मैं हास्केल के लिए नया हूं, और इस जवाब ने मुझे वास्तव में भाषा के कुछ चालाक सिद्धांतों को समझने में मदद की है (साथ ही, शुरुआती शुरुआत में थोड़ा टाइपो = ~ ~ ~~~ –

8

मेरा मानना ​​है कि (= ~) का उपयोग नहीं कर सकते हैं compOpt अन्य उपयोग करने के लिए defaultCompOpt से चाहते हैं तो उन्हें इस्तेमाल करने के पता नहीं है।

कुछ इस काम की तरह:

match (makeRegexOpts compCaseless defaultExecOpt "(Foo)" :: Regex) "foo" :: Bool 

दो लेख का पालन करें आपकी सहायता चाहिए:

Real World Haskell, Chapter 8. Efficient file processing, regular expressions, and file name matching

A Haskell regular expression tutorial

7

मैं हास्केल बारे में कुछ पता नहीं है, लेकिन आप PCRE के आधार पर एक regex पुस्तकालय उपयोग कर रहे हैं, तो आप नियमित अभिव्यक्ति के अंदर मोड संशोधक का उपयोग कर सकते हैं। "Caseless" एक मामले असंवेदनशील तरीके से मिलान करने के लिए, आप PCRE में इस regex का उपयोग कर सकते हैं: (? I)

(?i)caseless 

मोड संशोधक किसी भी मामले संवेदनशीलता या मामले असंवेदनशीलता विकल्प है कि नियमित अभिव्यक्ति के बाहर स्थापित किया गया था ओवरराइड करता है। यह ऑपरेटरों के साथ भी काम करता है जो आपको किसी भी विकल्प को सेट करने की अनुमति नहीं देते हैं।

इसी तरह, (? एस) "सिंगल लाइन मोड" चालू करता है जो डॉट मैच लाइन ब्रेक बनाता है, (? एम) "मल्टी लाइन मोड" चालू करता है जो^और लाइन ब्रेक पर $ मैच बनाता है, और (? X) फ्री-स्पेसिंग मोड चालू करता है (अनदेखी रिक्त स्थान और चरित्र वर्गों के बाहर लाइन ब्रेक महत्वहीन होते हैं)। आप अक्षरों को जोड़ सकते हैं। (? ismx) सब कुछ बदल जाता है। एक हाइफ़न विकल्प बंद कर देता है। (? -i) रेगेक्स केस संवेदनशील बनाता है। (? x-i) एक फ्री-रिक्ति केस संवेदनशील रेगेक्स शुरू करता है।

+0

यह भी काम करता है! स्वीकार्य समाधान –

+0

+1 से यह बहुत आसान है लेकिन कम जेनेरिक है, यह हमें idomatic '= ~' ऑपरेटर रखने और रेगेक्स को 'स्ट्रिंग' के रूप में परिभाषित करने की अनुमति देता है। अधिक बुनियादी! –

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