/ / हैश ऑब्जेक्ट में एक स्ट्रिंग शाब्दिक की तरह एक प्रतीक से मेल खाने के लिए रेगेक्स का उपयोग कैसे करें? - माणिक, रेगेक्स, हैश

एक हैश ऑब्जेक्ट में स्ट्रिंग शाब्दिक की तरह एक प्रतीक से मेल करने के लिए एक रेगेक्स का उपयोग कैसे करें? - माणिक, रेगेक्स, हैश

का उपयोग करते हुए str हैश में कुंजी ठीक काम करती है।

string = "The dog and cat"
replace = {"dog" => "woof", "cat" => "meow"}
replace.default = "unknown"

string.gsub(/w+/, replace)
# => "unknown woof unknown meow"

मैं एक ही परिणाम कैसे प्राप्त कर सकता हूं sym हैश की के रूप में?

string = "The dog and cat"
replace = {dog: "woof", cat: "meow"}
replace.default = "unknown"

string.gsub(/w+/, replace)
# => "unknown unknown unknown unknown" (actual result)
# => "unknown woof unknown meow" using symbols as hash keys? (desired result)

मेरे द्वारा किए गए कुछ प्रयास:

string.gsub(/(w+)/, replace[:$1])
# => "unknown unknown unknown unknown"

string.split.map(&:to_sym).to_s.gsub(/w+/, replace)
# => "[:unknown, :unknown, :unknown, :unknown]"

उत्तर:

जवाब के लिए 3 № 1

नीचे दिए गए कोड में:

string = "The dog and cat"
replace = {dog: "woof", cat: "meow"}
replace.default = "unknown"
string.gsub(/w+/, replace)

आपने हैश बनाया replace, डिफ़ॉल्ट मान के रूप में "unknown"। इसका मतलब है, जब आप हैश से एक मूल्य की तलाश करेंगे replace, यदि कुंजी मौजूद नहीं है, तो हैश आपको लौटा देगा unknown मान के रूप में। यह इस तरह से काम करेगा जैसे आपने इस तरह से हैश को परिभाषित किया है।

अभी व #gsub विधि, सभी शब्द मैच की तरह दे रही है "the", "dog" आदि, लेकिन उनमें से कोई भी स्ट्रिंग आपके हैश की कुंजी नहीं है replaceइस प्रकार, जैसा कि मैंने ऊपर कहा, हैश replace हर बार डिफ़ॉल्ट मान लौटाएगा unknown.

याद रखें - हैश में replace = {dog: "woof", cat: "meow"}, चाबियाँ प्रतीक हैं, जैसे :dog, :cat। परंतु #gsub तुम एक मैच के रूप में सभी मैच देता है तार.

इस प्रकार यह काम करने के लिए आपको नीचे ब्लॉक का उपयोग करने की आवश्यकता है:

string = "The dog and cat"
replace = {dog: "woof", cat: "meow"}
replace.default = "unknown"
string.gsub(/w+/) { |m| replace[m.to_sym] }
# => "unknown woof unknown meow"

उत्तर № 2 के लिए 1

यदि आप अन्य सभी शब्दों को रखना चाहते हैं, लेकिन बस हैश में क्या है, आप यह कर सकते हैं:

replace = {"dog" => "woof", "cat" => "meow"}
my_string = "The dog and cat"
my_string.gsub(/w+/) {|m| (replace.key? m) ? replace[m] : m}

जो उपज देगा:

The woof and meow

या अधिक संक्षेप में (संकेत के लिए @Arup के लिए धन्यवाद):

my_string.gsub(/w+/) {|m| replace.fetch(m, m)}

जवाब के लिए 0 № 3

यह स्पष्ट नहीं है कि आप "अज्ञात" शब्दों को क्यों बदलना चाहते हैं unknown; यह सामान्य में बहुत उपयोगी कुछ नहीं हैस्ट्रिंग प्रसंस्करण या टेम्पलेट-प्रोसेसिंग कोड। परिणामस्वरूप ऐसा लगता है जैसे आप "एक्स-वाई प्रश्न पूछना चाहते हैं, यह जानना चाहते हैं कि" वाई "कैसे करना है जब आपको वास्तव में" एक्स "करना चाहिए।

यहाँ कुछ कोड, और जानकारी जो मददगार हो सकती है:

string = "The dog and cat"
replacement_hash = {dog: "woof", cat: "meow"}

सबसे पहले, के साथ एक चर का उपयोग कर बहुत सावधान रहेंएक विधि के रूप में एक ही नाम। रूबी यह पता लगा सकती है कि आपका क्या मतलब है, लेकिन आपका मस्तिष्क हमेशा संबंध बनाने में विफल रहेगा। जो लोग आपके कोड का उपयोग करते हैं या बनाए रखते हैं, उनका दिमाग भी नहीं कर सकता है। इसलिए, एक हैश की बजाय बुलाया replace, कुछ का उपयोग करें replacement_hash.

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

replacement_hash2 = Hash[replacement_hash.keys.map(&:to_s).zip(replacement_hash.values)] # => {"dog"=>"woof", "cat"=>"meow"}

हम देना gsub एक नियमित अभिव्यक्ति, और यह स्ट्रिंग की तलाश में घूमेगाउस पैटर्न से मेल खाता है। इसकी एक शांत विशेषता यह है कि हम इसे एक हैश दे सकते हैं, और प्रत्येक मैच के लिए यह संबंधित हैश के माध्यम से दिखेगा और मिलान कुंजी के लिए मान लौटाएगा।

यहाँ हैश में कुंजियों से मेल खाने वाला पैटर्न आसानी से कैसे बनाया जाता है। मैं केस-असंवेदनशील पैटर्न का उपयोग कर रहा हूं, लेकिन YMMV:

key_regex = /b(?:#{ Regexp.union(replacement_hash.keys.map(&:to_s)).source })b/i # => /b(?:dog|cat)b/i

अपने सबसे बुनियादी रूप में, यहाँ एक है gsub एक हैश में मूल्यों को देखने के लिए एक पैटर्न का उपयोग करता है:

string.gsub(key_regex, replacement_hash2) # => "The woof and meow"

यह एक पैटर्न का उपयोग करके स्ट्रिंग को खोजना भी संभव है, फिर "हिट" को एक ब्लॉक में पास करें, जो तब आवश्यक प्रतिस्थापन की गणना करता है:

string.gsub(key_regex) { |w| replacement_hash2[w] } # => "The woof and meow"

या:

string.gsub(key_regex) { |w| replacement_hash[w.to_sym] } # => "The woof and meow"

पर रुको! अभी और है!

यदि आप सर्जिकल दृष्टिकोण नहीं चाहते हैं, तो आप अधिक जेनेरिक ("शॉटगन अप्रोच") रेगेक्स पैटर्न का भी उपयोग कर सकते हैं और हैश में देखने पर हिट और मिस दोनों को संभाल सकते हैं:

string.gsub(/S+/) { |w| replacement_hash[w.to_sym] || "unknown" } # => "unknown woof unknown meow"

यह आपके मूल कोड को कोड की एकल, सरल, लाइन में बदल देता है। आवश्यक के रूप में regexp बदलें।

इस पर ध्यान दें ब्लॉक के ऊपर की सामग्री नहीं है "

replacement_hash[:dog] # => "woof"
replacement_hash[:foo] # => nil
nil || "unknown" # => "unknown"

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

"foo".to_sym # => :foo
"foo_bar".to_sym # => :foo_bar
"foo-bar".to_sym # => :"foo-bar"
"foo bar".to_sym # => :"foo bar"