2008-08-21 10 views
13

मेरे पास एक बड़ा टेक्स्ट टेम्पलेट है जिसके लिए टोकनयुक्त अनुभागों को अन्य टेक्स्ट द्वारा प्रतिस्थापित किया गया है। टोकन इस तरह कुछ दिखते हैं: ## USERNAME ##। मेरा पहला वृत्ति सिर्फ स्ट्रिंग का उपयोग करने के लिए है। बदलें(), लेकिन क्या कोई बेहतर, अधिक कुशल तरीका है या इसके लिए पहले ही अनुकूलित किया गया है?बड़े टेक्स्ट टेम्पलेट में टोकन को प्रतिस्थापित करने का सबसे अच्छा तरीका

उत्तर

12

System.Text.RegularExpressions.Regex.Replace() वह है जो आप चाहते हैं - यदि आपके टोकन इतने अजीब हैं कि आपको उन्हें खोजने के लिए एक रेगेक्स की आवश्यकता है।

Some kind soul did some performance testing, और Regex.Replace(), String.Replace(), और StringBuilder.Replace(), String.Replace() वास्तव में शीर्ष पर बाहर आया।

+1

मुझे विश्वास है कि उन्होंने पावरशेल में अपना परीक्षण किया है जो सी # पर लागू नहीं होता है। सी 3 में पावरशेल से एक अलग मेमोरी प्रबंधन है और इसमें वर्णों को बदलने के लिए स्ट्रिंगबिल्डर को स्ट्रिंग में परिवर्तित नहीं किया गया है। दूसरी तरफ RegEx और StringBuilder बड़े डेटा आकारों पर बेहतर काम करते हैं जो उन्हें – AaA

+0

में जोड़ा गया है RegEx बड़ी मात्रा में पाठ पर प्रतिस्थापन करने के लिए एक भयानक विकल्प है। जितना शक्तिशाली है, कई रेगेक्स समर्थक पूरी दुनिया को एक नाखून और रेगेक्स के रूप में अपने हथौड़ा के रूप में देखते हैं। बड़ी मात्रा में टेक्स्ट शामिल मामलों के उपयोग के लिए, FastReplacer http://stackoverflow.com/a/11442008/141172 –

2

स्ट्रिंग। जगह ठीक है। मैं रेगेक्स का उपयोग करना पसंद करूंगा, लेकिन मैं नियमित अभिव्यक्तियों के लिए *** हूं।

ध्यान रखने योग्य बात यह है कि ये टेम्पलेट कितने बड़े हैं। यदि यह वास्तविक है, और स्मृति एक मुद्दा है, तो आप एक कस्टम टोकननाइज़र बनाना चाहते हैं जो स्ट्रीम पर कार्य करता है। इस तरह आप फ़ाइल में स्मृति का एक छोटा हिस्सा केवल स्मृति में रखते हैं जबकि आप इसका उपयोग करते हैं।

लेकिन, नैतिक कार्यान्वयन के लिए, स्ट्रिंग। जगह ठीक होनी चाहिए।

2

यदि आप बड़े तारों पर एकाधिक प्रतिस्थापन कर रहे हैं तो स्ट्रिंगबिल्डर का उपयोग करना बेहतर हो सकता है। रीप्लेस(), स्ट्रिंग के साथ सामान्य प्रदर्शन समस्याओं के रूप में दिखाई देगा।

2

हाल ही में ऐसा कुछ करना था। क्या मैंने किया था:

  • एक विधि (= डाला गया टेक्स्ट की जरूरत है कुंजी = टोकन नाम, मूल्य)
  • अपने टोकन स्वरूप (## करने के लिए सभी मैचों जाओ कि एक शब्दकोश ले जाता है + #।? # आपके मामले में, मुझे लगता है कि नियमित अभिव्यक्तियों पर यह अच्छा नहीं है: पी) Regex.Matchches (इनपुट, नियमित अभिव्यक्ति)
  • अपने टोकन के लिए सम्मिलित मूल्य खोजने के लिए शब्दकोश का उपयोग करके परिणामों पर foreach का उपयोग कर।
  • वापसी परिणाम।

हो गया ;-)

आप अपने regexes परीक्षण करना चाहते हैं मैं the regulator.

7

एकमात्र ऐसी स्थिति जिसमें मुझे यह करना है, एक टेम्पलेट ई-मेल भेज रहा है। .NET में यह MailDefinition class द्वारा बॉक्स से बाहर प्रदान किया जाता है। तो यह है कि कैसे आप एक टेम्प्लेट संदेश बनाने है:

MailDefinition md = new MailDefinition(); 
md.BodyFileName = pathToTemplate; 
md.From = "[email protected]"; 

ListDictionary replacements = new ListDictionary(); 
replacements.Add("<%To%>", someValue); 
// continue adding replacements 

MailMessage msg = md.CreateMailMessage("[email protected]", replacements, this); 

इस के बाद, msg.Body टेम्पलेट में मूल्यों प्रतिस्थापन द्वारा बनाई किया जाएगा। मुझे लगता है कि आप रिफ्लेक्टर के साथ MailDefinition.CreateMailMessage() पर एक नज़र डाल सकते हैं :)। थोड़ा ऑफ-विषय होने के लिए खेद है, लेकिन यदि यह आपका परिदृश्य है तो मुझे लगता है कि यह सबसे आसान तरीका है।

2

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

टोकन को परिभाषित करने के लिए एक बेहतर तरीका होगा, जैसे कि "##" जिसे आप पाठ में स्कैन कर सकते हैं।फिर कुंजी के रूप में टोकन का अनुसरण करने वाले पाठ के साथ हैश तालिका से प्रतिस्थापित करने का चयन करें।

यदि यह बिल्ड स्क्रिप्ट का हिस्सा है तो nAnt में Filter Chains नामक करने के लिए एक शानदार सुविधा है। इसके लिए कोड ओपन सोर्स है ताकि आप देख सकें कि यह तेजी से कार्यान्वयन के लिए कैसे किया जाता है।

3

ठीक है, आपके टेम्पलेट में आपके पास कितने चर हैं, आपके पास कितने टेम्पलेट हैं, आदि के आधार पर यह एक पूर्ण टेम्पलेट प्रोसेसर के लिए एक काम हो सकता है। .NET के लिए मैंने कभी भी उपयोग किया है, केवल NVelocity है, लेकिन मुझे यकीन है कि वहां कई अन्य लोग होंगे, जिनमें से अधिकांश कुछ वेब ढांचे या किसी अन्य से जुड़े हैं।

1

यदि आपका टेम्पलेट बड़ा है और आपके पास बहुत सारे टोकन हैं, तो शायद आप इसे चलना नहीं चाहते हैं और टेम्पलेट में टोकन को एक-एक करके बदलना चाहते हैं जिसके परिणामस्वरूप ओ (एन * एम) ऑपरेशन होगा जहां एन है टेम्पलेट का आकार और एम प्रतिस्थापित करने के लिए टोकन की संख्या है।

निम्न विधि एक टेम्पलेट और चाबियाँ मान जोड़ों का एक शब्दकोश स्वीकार करती है जिन्हें आप प्रतिस्थापित करना चाहते हैं। स्ट्रिंगबिल्डर को टेम्पलेट के आकार की तुलना में थोड़ा बड़ा करने के द्वारा, इसका परिणाम ओ (एन) ऑपरेशन होना चाहिए (यानी इसे खुद को एन बार लॉग नहीं करना चाहिए)।

अंत में, आप टोकन की इमारत को सिंगलटन में स्थानांतरित कर सकते हैं क्योंकि इसे केवल एक बार उत्पन्न होने की आवश्यकता है।

static string SimpleTemplate(string template, Dictionary<string, string> replacements) 
{ 
    // parse the message into an array of tokens 
    Regex regex = new Regex("(##[^#]+##)"); 
    string[] tokens = regex.Split(template); 

    // the new message from the tokens 
    var sb = new StringBuilder((int)((double)template.Length * 1.1)); 
    foreach (string token in tokens) 
     sb.Append(replacements.ContainsKey(token) ? replacements[token] : token); 

    return sb.ToString(); 
} 
2

FastReplacer हे में टोकन प्रतिस्थापन (एन * लॉग (एन) + m) समय लागू करता है और 3x मूल स्ट्रिंग की स्मृति का उपयोग करता है।

फास्ट रेप्लसर प्रदर्शन के महत्वपूर्ण होने पर एक बड़ी स्ट्रिंग पर कई प्रतिस्थापन संचालन निष्पादित करने के लिए अच्छा है।

मुख्य विचार मौजूदा पाठ को संशोधित करने या स्ट्रिंग प्रतिस्थापित होने पर हर बार नई मेमोरी आवंटित करने से बचाना है।

हमने फास्ट रेप्लसर को एक परियोजना पर हमारी सहायता करने के लिए डिज़ाइन किया है जहां हमें बड़ी संख्या में संलग्न करने और संचालन को बदलने के साथ एक बड़ा टेक्स्ट बनाना था। आवेदन के पहले संस्करण में स्ट्रिंगबिल्डर का उपयोग करके टेक्स्ट उत्पन्न करने में 20 सेकंड लग गए। स्ट्रिंग क्लास का उपयोग करने वाले दूसरे उन्नत संस्करण में 10 सेकंड लग गए। फिर हमने FastReplacer लागू किया और अवधि 0.1 सेकंड तक गिर गई।

+0

देखें, यह वही है जो मैं ढूंढ रहा था। कृपया स्पीड टेबल की जांच करें और इसे आज़माएं। –

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

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