2010-05-22 13 views
7

इस जावास्क्रिप्ट पर विचार करें:जावास्क्रिप्ट Regex ब्रैकेट अंकन करने के लिए डॉट नोटेशन कन्वर्ट करने के लिए

var values = { 
    name: "Joe Smith", 
    location: { 
     city: "Los Angeles", 
     state: "California" 
    } 
} 

var string = "{name} is currently in {location.city}, {location.state}"; 

var out = string.replace(/{([\w\.]+)}/g, function(wholematch,firstmatch) { 
    return typeof values[firstmatch] !== 'undefined' ? 
     values[firstmatch] : wholematch; 
}); 

हो जाएगा ताकि उत्पादन निम्नलिखित:

Joe Smith is currently in Los Angeles, California 
:

Joe Smith is currently in {location.city}, {location.state} 

लेकिन मैं निम्नलिखित उत्पादन करना चाहते हैं

मैं स्ट्रिंग में ब्रेसिज़ के बीच कई बिंदुओं में डॉट नोटेशन के कई स्तरों को परिवर्तित करने का एक अच्छा तरीका ढूंढ रहा हूं मापदंडों ब्रैकेट अंकन के साथ इस्तेमाल किया जा रहा, इस तरह:

:

values[first][second][third][etc] 

मूलतः, यह उदाहरण के लिए, मैं यह पता लगाने की कोशिश कर रहा हूँ क्या regex स्ट्रिंग और समारोह मैं के बराबर के साथ खत्म करने की आवश्यकता होगी

out = values[name] + " is currently in " + values["location"]["city"] + 
    values["location"]["state"]; 

नोट: मैं eval() का उपयोग किए बिना ऐसा करना चाहता हूं।

+0

बस एक टाइपो देखा है। 'Var joe' से 'var values' को नामित किया गया – Tauren

+0

एक और समान प्रश्न के उत्तर में @ जे-पी द्वारा वैकल्पिक समाधान है। यह काफी सुरुचिपूर्ण दिखता है: http://stackoverflow.com/questions/3344392/dynamic-deep-selection-for-a-javascript-object/3344487#3344487 – Tauren

उत्तर

10

iteratively गुण का उपयोग करने की एक सहायक समारोह का उपयोग करना:

function getNestedValue(obj, prop) { 
    var value, props = prop.split('.'); // split property names 

    for (var i = 0; i < props.length; i++) { 
    if (typeof obj != "undefined") { 
     obj = obj[props[i]]; // go next level 
    } 
    } 
    return obj; 
} 

var string = "{name} is currently in {location.city}, {location.state}"; 

var out = string.replace(/{([^}]+)}/g, function(wholematch,firstmatch) { 
    var value = getNestedValue(joe, firstmatch); 
    return typeof value !== 'undefined' ? value : wholematch; 
}); 
// "Joe Smith is currently in Los Angeles, California" 

ऊपर के उदाहरण here की कोशिश करो।

संपादित: कुछ थोड़ा सुरुचिपूर्ण, Array.prototype.reduce विधि का उपयोग कर, नए ECMAScript 5 वें संस्करण स्टैंडर्ड का हिस्सा:

function replace(str, obj) { 
    return str.replace(/{([^}]+)}/g, function(wholematch,firstmatch) { 
    var value = firstmatch.split('.').reduce(function (a, b) { 
     return a[b]; 
    }, obj); 
    return typeof value !== 'undefined' ? value : wholematch; 
    }); 
} 

replace("{name} is currently in {location.city}, {location.state}", values); 
// "Joe Smith is currently in Los Angeles, California" 

नया उदाहरण here की कोशिश करो।

+0

@CMS: अच्छा, यह काम करता है! हालांकि, यह रेगेक्स-आधारित समाधान के रूप में सुरुचिपूर्ण प्रतीत नहीं होता है, और मुझे विश्वास है कि ऐसा करने के लिए एक रेगेक्स तरीका है। फिर फिर, शायद यह एक regex समाधान पीछा करने के लिए समय बर्बाद हो जाएगा। – Tauren

+0

@ सीएमएस: क्या आपकी रेगेक्स ब्रेसिज़ के बीच कुछ भी अनुमति नहीं देती है? अगर मैं मान्य जावास्क्रिप्ट चर नामों ['a-zA-Z0-9 _ \।]' मानों को सीमित करना चाहता हूं, तो यह '/ {([\ w \।] +)}/g' का उपयोग करना सबसे अच्छा नहीं होगा?असल में, यह शुरुआत की अवधि की अनुमति देगा, जिसकी अनुमति नहीं है, लेकिन यह करीब है। ओह हाँ, मुझे लगता है कि मुझे '$' भी शामिल करना होगा। – Tauren

+0

@Tauren, ठीक है यह थोड़ा अनुमोदित है, मुझे बहुत ज्यादा परवाह नहीं है, क्योंकि जब आप ब्रैकेट नोटेशन (या ऑब्जेक्ट शाब्दिक में तारों का उपयोग करते हैं) के साथ गुणों का उपयोग करते हैं, तो कोई प्रतिबंध नहीं है, यानी 'obj ["3.xx \ u0009 "]' – CMS

0

मुझे यकीन है कि कैसे जावास्क्रिप्ट में इस एकीकृत करने के लिए नहीं कर रहा हूँ, लेकिन यहाँ एक जावा टुकड़ा परिवर्तन की जरूरत है ऐसा करने के लिए regex का उपयोग करता है है: मूलतः यह

[name] 
[location][city] 
[location][state][zip][bleh] 

:

String[] tests = { 
     "{name}", 
     "{location.city}", 
     "{location.state.zip.bleh}", 
    }; 
    for (String test : tests) { 
     System.out.println(test.replaceAll("\\{?(\\w+).?", "[$1]")); 
    } 

यह प्रिंट \{?(\w+).? से [$1] की सभी घटनाओं को प्रतिस्थापित करता है।

+0

हम्म, दिलचस्प। हालांकि, अगर मुझे यह जेएस में काम कर रहा है, तो भी मुझे लगता है कि मैं एक स्ट्रिंग के साथ समाप्त हो जाऊंगा जिसे मुझे 'eval' करने की आवश्यकता होगी, जिसे मैं टालना चाहता हूं। – Tauren

0

आप comp.lang.javascript पर पोस्ट किए गए विषय Error-free deep property access? पर एक नज़र डाल सकते हैं - यह आपके इच्छित काम करने के लिए कई दृष्टिकोण प्रस्तुत करता है।

regexp के लिए, आप सभी की जरूरत /{.*?}/g

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