2011-06-23 2 views
9

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

जिस कार्यक्षमता को मैं ढूंढ रहा हूं वह सरल है। उदाहरण के लिए, निम्नलिखित पैटर्न दिए गए हैं, यहां मैचों हैं:

pattern | test-string   | match 
========|=====================|==================== 
*hn  | john, johnny, hanna | true , false, false  # wildcard , similar to /hn$/i 
*hn* | john, johnny, hanna | true , true , false  # like /hn/i 
hn  | john, johnny, hanna | false, false, false  # /^hn$/i 
*h*n* | john, johnny, hanna | true , true , true 
etc... 

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

संपादित: मैं रूबी 1.8.7

उत्तर

13

डी मैं नहीं दिख रहा है: यह परीक्षण नहीं किया गया है आप क्यों सोचते हैं कि यह अक्षम होगा। इस तरह के चीजों के बारे में भविष्यवाणियां कुख्यात अविश्वसनीय हैं, आपको यह तय करना चाहिए कि तेजी से रास्ता खोजने के लिए पीछे की तरफ झुकने से पहले यह बहुत धीमा है। और फिर आपको यह सुनिश्चित करने के लिए प्रोफाइल करना चाहिए कि यह समस्या है जहां समस्या है (बीटीडब्ल्यू स्विचिंग से 3-4x की गति वृद्धि का औसत 1.9)

वैसे भी, ऐसा करना बहुत आसान होना चाहिए, कुछ ऐसा : - वाक्यविन्यास त्रुटियों ओर इशारा करते हुए के लिए धन्यवाद -

class Globber 
    def self.parse_to_regex(str) 
    escaped = Regexp.escape(str).gsub('\*','.*?') 
    Regexp.new "^#{escaped}$", Regexp::IGNORECASE 
    end 

    def initialize(str) 
    @regex = self.class.parse_to_regex str 
    end 

    def =~(str) 
    !!(str =~ @regex) 
    end 
end 


glob_strs = { 
    '*hn' => [['john', true, ], ['johnny', false,], ['hanna', false]], 
    '*hn*' => [['john', true, ], ['johnny', true, ], ['hanna', false]], 
    'hn'  => [['john', false,], ['johnny', false,], ['hanna', false]], 
    '*h*n*' => [['john', true, ], ['johnny', true, ], ['hanna', true ]], 
} 

puts glob_strs.all? { |to_glob, examples| 
    examples.all? do |to_match, expectation| 
    result = Globber.new(to_glob) =~ to_match 
    result == expectation 
    end 
} 
# >> true 
+0

मैं की ' '* उदाहरण के लिए hn'', वह की जरूरत है'' मामले में लगता है कि जॉन awesome'' है सच भी लौटने के लिए, और '/.* एचएन $ /' –

+0

से मेल नहीं खाएगा ऐसा लगता है कि मेरे कंप्यूटर (मैक ओएसएक्स तेंदुए) पर ग्लोब काम करने का तरीका नहीं है https://gist.github.com/1041942 –

+0

I मान लीजिए वाइल्डकार्ड मेरे उद्देश्य के लिए ग्लोब से अधिक सटीक है - '' * hn '' के मामले में मुझे पसंद आएगा ई सब कुछ पहले और ऊपर-पैटर्न के मिलान के लिए, और कुछ भी नहीं; इसलिए 'जॉन' के लिए 'सत्य', 'जॉन' के लिए 'झूठा' .. '। धन्यवाद – sa125

1
def create_regex(pattern) 
if pattern[0,1] != '*' 
    pattern = '[^\w\^]' + pattern 
end 
if pattern[-1,1] != '*' 
    pattern = pattern + '[^\w$]' 
end 
return Regexp.new(pattern.gsub(/\*/, '.*?')) 
end 

उपयोग कर रहा हूँ इस methoid अपने regexp लौटना चाहिए

पुनश्च:

+2

कुछ संपादन किया बहुत ज्यादा पर्ल/php: डी –