2008-08-29 15 views
8

मैं एक सी ++ कोड बेस पर काम कर रहा हूं जिसे हाल ही में एक्स/मोटीफ से क्यूटी तक ले जाया गया था। मैं एक पर्ल स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो बूल के साथ बूलियन (एक्स से) की सभी घटनाओं को प्रतिस्थापित करेगा। लिपि बस एक साधारण प्रतिस्थापन करता है।बूलियन को बूल के साथ बदलने के लिए रेगेक्स

s/\bBoolean\b/bool/g 

कुछ स्थितियां हैं।

1) हमारे पास हमारे कोड में कॉर्बा है और \ b मैर कॉरबा :: बूलियन है जो नहीं बदला जाना चाहिए।
2) अगर यह (स्ट्रिंग के रूप मिला था यानी "बूलियन" यह मेल नहीं चाहिए)

अपडेट किया गया:

# 1 के लिए, मैं lookbehind

s/(?<!:)\bBoolean\b/bool/g; 

इस्तेमाल किया # 2 के लिए , मैंने लुकहेड का इस्तेमाल किया।

s/(?<!:)\bBoolean\b(?!")/bool/g</pre> 

यह मेरी स्थिति के लिए सबसे अधिक संभावना है लेकिन निम्नलिखित सुधारों के बारे में कैसे होगा?

3) स्ट्रिंग के बीच में मिलान न करें (धन्यवाद nohat)।
4) किसी टिप्पणी में अगर मेल नहीं खाते। (// या/** /)

+0

साइड नोट: http://stackoverflow.com/questions/72312/how-should-i-capitalize-perl#72757 – szabgab

उत्तर

0

हालत ठीक करने के लिए 1 कोशिश:

s/[^:]\bBoolean\b(?!")/bool/g 

[^:] के अलावा अन्य किसी भी चरित्र से मेल करने के कहते हैं, ":"।

1
s/[^:]\bBoolean\b[^"]/bool/g 

संपादित करें: चूहों, फिर से पीटा। मुझे मारने के लिए +1, अच्छा महोदय।

3

एस/[^:] \ bBoolean \ बी/bool/जी

इस तार से मेल नहीं खाता जहां बूलियन पर है कि क्योंकि [पंक्ति के आरंभ^("?!): ] कि "एक चरित्र है कि नहीं है से मेल खाते हैं:"

2

कि बोली-मिलान अग्रदर्शी दावे से बाहर देखो यह केवल यदि बूलियन के बीच में एक स्ट्रिंग के अंतिम हिस्सा है, लेकिन नहीं की भरपाई करेंगे।। स्ट्रिंग। यदि आप यह सुनिश्चित करना चाहते हैं कि आप स्ट्रिंग में नहीं हैं (किसी मल्टी-लाइन स्ट्रिंग को मानते हुए आपको मिलान से पहले उद्धरण चिह्नों की संख्या भी मिलनी होगी एस और कोई एम्बेडेड उद्धरण चिह्न से बच निकला)।

0

3) स्ट्रिंग के बीच में (धन्यवाद नोहाट) में मेल न करें।

आप शायद "। * बूलियन। *" जांचने के लिए एक reg ex लिख सकते हैं। लेकिन क्या होगा यदि आपके पास स्ट्रिंग के अंदर उद्धरण (") है? तो, आपके पास पैटर्न (\") को बाहर करने के लिए और अधिक काम नहीं है।

4) किसी टिप्पणी में मिलान न करें। (// या/* * /)

'//' के लिए, आप // को बाहर करने के लिए एक regex हो सकता है।* लेकिन, // टिप्पणियों ((। *) (//.*)) के लिए पूरी लाइन की तुलना करने के लिए पहले एक रेगेक्स डालना बेहतर हो सकता है और फिर केवल $ 1 (पहले मिलान पैटर्न) पर प्रतिस्थापन लागू करें।

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

अब, यदि आपके पास // * या * // // ब्लॉक के अंदर क्या है? (मुझे नहीं पता कि आपके पास यह क्यों होगा .. लेकिन मर्फी का कानून कहता है कि आप इसे प्राप्त कर सकते हैं)। स्पष्ट रूप से कुछ रास्ता निकला है लेकिन मेरा विचार यह है कि रेगेक्स कितना खराब दिख रहा है।

मेरा सुझाव यहां सी ++ के लिए कुछ व्याख्यात्मक उपकरण का उपयोग करना होगा और टोकन के साथ टोकन बूलियन को प्रतिस्थापित करना होगा। तुम्हारे विचार?

0

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

0
  1. ...
  2. ...
  3. से मेल नहीं है एक स्ट्रिंग के बीच में अगर (nohat धन्यवाद)।
  4. कोई टिप्पणी में अगर मेल नहीं खाते। (// या/** /)

कोई एक सरल regex के साथ क्या कर सकते हैं। इसके लिए, आपको वास्तव में प्रत्येक एकल वर्ण बाएं से दाएं को देखने की आवश्यकता है और यह तय करें कि यह कितनी चीज है, कम से कम अच्छी तरह से अन्य सामानों से तारों से बहु-पंक्ति टिप्पणियों से अलग टिप्पणियां बताने के लिए पर्याप्त है, और आपको यह देखने की ज़रूरत है कि "अन्य सामान" भाग में वे चीज़ें हैं जिन्हें आप बदलना चाहते हैं।

अब, मैं सी में टिप्पणियों और तार के लिए सटीक वाक्य-नियम पता नहीं ++ तो निम्नलिखित अनिश्चित और पूरी तरह से undebugged होने जा रहा है, लेकिन यह आप जटिलता आप कर रहे हैं की एक विचार दे देंगे विरुद्ध।

my $line_comment  = qr! (?> // .* \n?) !x; 
my $multiline_comment = qr! (?> /\* [^*]* (?: \* (?: [^/*] [^*]*)?)*)* \*/) !x; 
my $string   = qr! (?> " [^"\\]* (?: \\ . [^"\\]*)* ") !x; 
my $boolean_type  = qr! (?<!:) \b Boolean \b !x; 

$code =~ s{ \G (
     $line_comment 
    | $multiline_comment 
    | $string 
    | ($boolean_type) 
    | . 
) }{ 
    defined $2 ? 'bool' : $1 
}gex; 

कृपया मुझे इसकी सभी जटिलताओं में यह बताने के लिए मत कहें, यह मुझे एक दिन और दूसरा ले जाएगा। जेफ   फ्रेडल Mastering Regular Expressions खरीदें और पढ़ें यदि आप समझना चाहते हैं कि यहां क्या हो रहा है।

0

"एक स्ट्रिंग के बीच में 'बूलियन'" हिस्सा थोड़ा संभावना नहीं लगता है, मैं पहली बार जाँच चाहते हैं, तो वहाँ की तरह

m/"[^"]*Boolean[^"]*"/ 

और वहाँ अगर कुछ के साथ कोड में इसके किसी भी घटना है कोई भी या कुछ नहीं है, बस उस मामले को अनदेखा करें।

1
#define Boolean bool 

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

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