2012-09-11 18 views
6

मैं कैसे जांच सकता हूं कि एक स्ट्रिंग में एक सबस्ट्रिंग है, लेकिन केवल एक विशिष्ट स्थिति में?जांचें कि क्या एक स्ट्रिंग में एक शब्द है लेकिन केवल विशिष्ट स्थिति में है?

उदाहरण स्ट्रिंग:

अपने पसंदीदा रंग क्या है? मेरी [पसंदीदा] रंग नीला

है अगर मैं अगर स्ट्रिंग किसी विशिष्ट शब्द मैं आमतौर पर ऐसा करने के निहित जाँच करने के लिए चाहता था:

var 
    S: string; 
begin 
    S := 'What is your favorite color? my [favorite] color is blue'; 
    if (Pos('favorite', S) > 0) then 
    begin 
    // 
    end; 
end; 

क्या मैं जरूरत है निर्धारित करने के लिए शब्द पसंदीदा स्ट्रिंग में मौजूद है, हालांकि यह अनदेखा करता है कि यह [] प्रतीकों के अंदर दिखाई देता है, जो उपर्युक्त कोड नमूना स्पष्ट रूप से नहीं करता है।

तो अगर हम एक बूलियन समारोह में कोड डाल दिया, कुछ नमूना परिणाम इस प्रकार दिखाई देगा:

सही: अपने पसंदीदा रंग क्या है? मेरी [मेरी पसंदीदा] रंग नीला है

सही: अपने पसंदीदा रंग क्या है? मेरी [, ऐसा] रंग नीला है

गलत: अपने , ऐसा रंग क्या है? मेरी [कुछ पसंदीदा] रंग नीला

पहले दो नमूने ऊपर सत्य हैं, क्योंकि शब्द पसंदीदा [] प्रतीकों में से बाहर पाया जाता है, चाहे वह उन्हें अंदर नहीं है या।

तीसरा नमूना झूठा है क्योंकि भले ही पसंदीदा शब्द है, यह केवल [] प्रतीकों के अंदर दिखाई देता है - हमें केवल यह जांचना चाहिए कि यह प्रतीकों के बाहर मौजूद है या नहीं।

तो मुझे यह निर्धारित करने के लिए एक फ़ंक्शन चाहिए कि कोई शब्द (इस उदाहरण में पसंदीदा) स्ट्रिंग में दिखाई देता है, लेकिन तथ्य को अनदेखा कर रहा है कि शब्द [] प्रतीकों के अंदर घिरा हुआ है या नहीं।

+0

विचार: 1) '\ s' पर स्ट्रिंग को विभाजित करें और चौथे तत्व की जांच करें। 2) 'पसंदीदा' के लिए जांचें (शब्द के चारों ओर रिक्त स्थान नोट करें)। 3) स्ट्रिंग को प्रश्न चिह्न '?' पर विभाजित करें और फिर जांचें कि क्या यह 'पसंदीदा' है या नहीं। –

+5

खोज '[', अगर खोज मिली ']', '[]' के बीच में हटाएं, पसंदीदा के लिए खोजें। –

+0

या '\ b' + wordtofind + '\ b''' के रेगेक्स के साथ नियमित अभिव्यक्ति (XE में शामिल इकाइयों के साथ) का उपयोग करें। केवल एक चीज जिसे आप देखना चाहते हैं वह 'क्या यह आपका पसंदीदा है?', जहां '?' इसे मेल नहीं करेगा। –

उत्तर

8

मुझे ब्रैकेट द्वारा संलग्न तारों को हटाने और उसके बाद एक स्ट्रिंग की खोज करने के बारे में Sertac's idea पसंद है।

function ContainsWord(const AText, AWord: string; AWholeWord: Boolean = True; 
    ACaseSensitive: Boolean = False): Boolean; 
var 
    S: string; 
    BracketEnd: Integer; 
    BracketStart: Integer; 
    SearchOptions: TStringSearchOptions; 
begin 
    S := AText; 
    BracketEnd := Pos(']', S); 
    BracketStart := Pos('[', S); 
    while (BracketStart > 0) and (BracketEnd > 0) do 
    begin 
    Delete(S, BracketStart, BracketEnd - BracketStart + 1); 
    BracketEnd := Pos(']', S); 
    BracketStart := Pos('[', S); 
    end; 
    SearchOptions := [soDown]; 
    if AWholeWord then 
    Include(SearchOptions, soWholeWord); 
    if ACaseSensitive then 
    Include(SearchOptions, soMatchCase); 
    Result := Assigned(SearchBuf(PChar(S), StrLen(PChar(S)), 0, 0, AWord, 
    SearchOptions)); 
end; 

यहाँ समारोह है, जो स्ट्रिंग परिवर्तन के बिना सूचक चार यात्रा का उपयोग करता है की एक अनुकूलित संस्करण है: यहाँ एक कोड नमूना पूरे शब्द और मामले की संवेदनशीलता के लिए एक खोज के लिए बढ़ा दी है। पिछले संस्करण की तुलना में यह मामला संभालता है जब आपके पास अनुपलब्ध बंद ब्रैकेट के साथ स्ट्रिंग है जैसे उदाहरण My [favorite color is। इस तरह की स्ट्रिंग को उस लापता ब्रैकेट की वजह से सच में मूल्यांकन किया गया है।

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

इस कोड follow this link की टिप्पणी की संस्करण के लिए

function ContainsWord(const AText, AWord: string; AWholeWord: Boolean = True; 
    ACaseSensitive: Boolean = False): Boolean; 
var 
    CurrChr: PChar; 
    TokenChr: PChar; 
    TokenLen: Integer; 
    SubstrChr: PChar; 
    SubstrLen: Integer; 
    SearchOptions: TStringSearchOptions; 
begin 
    Result := False; 
    if (Length(AText) = 0) or (Length(AWord) = 0) then 
    Exit; 
    SearchOptions := [soDown]; 
    if AWholeWord then 
    Include(SearchOptions, soWholeWord); 
    if ACaseSensitive then 
    Include(SearchOptions, soMatchCase); 
    CurrChr := PChar(AText); 
    SubstrChr := CurrChr; 
    SubstrLen := 0; 
    while CurrChr^ <> #0 do 
    begin 
    if CurrChr^ = '[' then 
    begin 
     TokenChr := CurrChr; 
     TokenLen := 0; 
     while (TokenChr^ <> #0) and (TokenChr^ <> ']') do 
     begin 
     Inc(TokenChr); 
     Inc(TokenLen); 
     end; 
     if TokenChr^ = #0 then 
     SubstrLen := SubstrLen + TokenLen; 
     Result := Assigned(SearchBuf(SubstrChr, SubstrLen, 0, 0, AWord, 
     SearchOptions)); 
     if Result or (TokenChr^ = #0) then 
     Exit; 
     CurrChr := TokenChr; 
     SubstrChr := CurrChr; 
     SubstrLen := 0; 
    end 
    else 
    begin 
     Inc(CurrChr); 
     Inc(SubstrLen); 
    end; 
    end; 
    Result := Assigned(SearchBuf(SubstrChr, SubstrLen, 0, 0, AWord, 
    SearchOptions)); 
end; 
+1

ग्रेट उत्तर, विशेष रूप से उपयोगी टिप्पणियों के उत्तर का लिंक है, यह पचाने और समझने में थोड़ा आसान बनाता है कि क्या हो रहा है। –

+1

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

7

regular expressions में, look-around नामक एक चीज़ है जिसका आप उपयोग कर सकते हैं। आपके मामले में आप नकारात्मक दिखने के साथ इसे हल कर सकते हैं: आप "पसंदीदा" चाहते हैं जब तक कि यह एक उद्घाटन ब्रैकेट से पहले न हो। यह ऐसा दिखाई दे सकता:

(?<!\[[^\[\]]*)favorite 

चरण कदम से: [^\[\]]* नकारात्मक, बंद: (?<! नकारात्मक lookbehind उपसर्ग, हम \[ लिए देख रहे हैं वैकल्पिक रूप से कोई भी या अधिक चीजें हैं जो बंद करने या कोष्ठक नहीं खुल रही हैं जिसके बाद ) के साथ देखो, और उसके बाद favorite ठीक बाद में देखें।

+0

मुझे लगता है कि आपका एक सुरुचिपूर्ण और उचित समाधान है – diegoaguilar

0

मुझे लगता है कि आप अपनी समस्या को दोबारा बता सकते हैं "प्रदान की गई स्ट्रिंग का एक ऑक्करेंस स्क्वायर ब्रैकेट से घिरा नहीं है।" यदि यह आपकी समस्या का वर्णन करता है, तो आप आगे बढ़ सकते हैं और [^\[]favorite[^\]] जैसी सरल नियमित अभिव्यक्ति का उपयोग कर सकते हैं।

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