2011-08-11 5 views
27

एक स्ट्रिंग में कई बार होता है जो एक बार होता है। मैं rangeOfString का उपयोग करता हूं, लेकिन ऐसा लगता है कि यह केवल पहला स्थान ढूंढ सकता है। मैं सबस्ट्रिंग के सभी स्थानों को कैसे ढूंढ सकता हूं?एनएसएसटींग में सबस्ट्रिंग के सभी स्थानों को ढूंढें (केवल पहले नहीं)

NSString *subString1 = @"</content>"; 
NSString *subString2 = @"--\n"; 
NSRange range1 = [newresults rangeOfString:subString1]; 
NSRange range2 = [newresults rangeOfString:subString2]; 
int location1 = range1.location; 
int location2 = range2.location; 
NSLog(@"%i",location1); 
NSLog(@"%i",location2); 
+0

याचिका का पता लगाएं से अधिक स्पष्ट अपने प्रश्न बना ... –

+1

मैं [NSRegularExpressions] में [1] [1] दिखेगा: http://stackoverflow.com/questions/4353834/search-through-nsstring-using- नियमित अभिव्यक्ति – EricS

उत्तर

70

आप rangeOfString:options:range: का उपयोग करें और तीसरा तर्क सेट पहली घटना की सीमा से परे हो सकता है। उदाहरण के लिए, आप कुछ इस तरह कर सकते हैं:

NSRange searchRange = NSMakeRange(0,string.length); 
NSRange foundRange; 
while (searchRange.location < string.length) { 
    searchRange.length = string.length-searchRange.location; 
    foundRange = [string rangeOfString:substring options:nil range:searchRange]; 
    if (foundRange.location != NSNotFound) { 
     // found an occurrence of the substring! do stuff here 
     searchRange.location = foundRange.location+foundRange.length; 
    } else { 
     // no more substring to find 
     break; 
    } 
} 
+4

यह मानता है कि सबस्ट्रिंग उपस्थितियां ओवरलैप नहीं होती हैं, जो सवाल पर विचार करने के लिए उचित है। आम तौर पर यह एक उचित धारणा नहीं हो सकती है। घाटी पर विचार करें "ababab"। सुई "अबाब" स्थिति 0 और स्थिति 2 पर दिखाई देती है (सुई को स्थिति 0 पर ओवरलैप करना)। उपरोक्त एल्गोरिदम द्वारा स्थिति 2 को अनदेखा किया जाएगा। – kevinlawler

+3

टेक्स्ट "+1" टेक्स्ट को "+1 मिला" टेक्स्ट में बदलना उचित तरीके से एल्गोरिदम को संशोधित करता है। – kevinlawler

1

को नहीं के बराबर पासिंग [स्ट्रिंग rangeOfString: सबस्ट्रिंग विकल्प: शून्य सीमा: searchRange]; एक चेतावनी दिखाता है।

, इस समूह

enum { 
    NSCaseInsensitiveSearch = 1, 
    NSLiteralSearch = 2, 
    NSBackwardsSearch = 4, 
    NSAnchoredSearch = 8, 
    NSNumericSearch = 64, 
    NSDiacriticInsensitiveSearch = 128, 
    NSWidthInsensitiveSearch = 256, 
    NSForcedOrderingSearch = 512, 
    NSRegularExpressionSearch = 1024 
}; 

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/doc/constant_group/Search_and_Comparison_Options

0

यहाँ से एक enum में डाल चेतावनी से छुटकारा पाने के लिए एक kevinlawler और Gibtang

से इनपुट के साथ PengOne के जवाब की स्विफ्ट 2.2 में संस्करण है नोट: स्ट्रिंग और सबस्ट्रिंग प्रकार एनएसएसटींग

let fullStringLength = (string as String).characters.count 
var searchRange = NSMakeRange(0, fullStringLength) 
while searchRange.location < fullStringLength { 
    searchRange.length = fullStringLength - searchRange.location 
    let foundRange = string.rangeOfString(substring as String, options: .CaseInsensitiveSearch, range: searchRange) 
    if foundRange.location != NSNotFound { 
     // found an occurrence of the substring! do stuff here 
     searchRange.location = foundRange.location + 1 
    } else { 
     // no more strings to find 
     break 
    } 
} 
2

यह मेरा समाधान है। असल में, एल्गोरिदम स्ट्रिंग को मैट्रिंग मैचों की तलाश में स्ट्रिंग करता है और उन मैचों को सरणी में देता है।

एनएसआरेंज एक संरचना है जिसे इसे सरणी में सीधे जोड़ा नहीं जा सकता है। NSValue का उपयोग करके, मैं एन्कोड पहले मैच को एन्कोड कर सकता हूं और फिर इसे सरणी में जोड़ सकता हूं। सीमा को पुनः प्राप्त करने के लिए, मैं डीकोडNSValue ऑब्जेक्ट एनएसआरेंज पर ऑब्जेक्ट।

#import <Foundation/Foundation.h> 

NSRange makeRangeFromIndex(NSUInteger index, NSUInteger length) { 
    return NSMakeRange(index, length - index); 
} 

NSArray<NSValue *> * allLocationsOfStringMatchingSubstring(NSString *text, NSString *pattern) { 
    NSMutableArray *matchingRanges = [NSMutableArray new]; 
    NSUInteger textLength = text.length; 
    NSRange match = makeRangeFromIndex(0, textLength); 

    while(match.location != NSNotFound) { 
     match = [text rangeOfString:pattern options:0L range:match]; 
     if (match.location != NSNotFound) { 
      NSValue *value = [NSValue value:&match withObjCType:@encode(NSRange)]; 
      [matchingRanges addObject:value]; 
      match = makeRangeFromIndex(match.location + 1, textLength); 
     } 
    } 

    return [matchingRanges copy]; 
} 

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     NSString *text = @"TATACCATGGGCCATCATCATCATCATCATCATCATCATCATCACAG"; 
     NSString *pattern = @"CAT"; 
     NSArray<NSValue *> *matches = allLocationsOfStringMatchingSubstring(text, pattern); 

     NSLog(@"Text: %@", text); 
     NSLog(@"Pattern: %@", pattern); 
     NSLog(@"Number of matches found: %li", matches.count); 

     [matches enumerateObjectsUsingBlock:^(NSValue *obj, NSUInteger idx, BOOL *stop) { 
      NSRange match; 
      [obj getValue:&match]; 
      NSLog(@" Match found at index: %li", match.location); 
     }]; 
    } 
    return 0; 
} 
0

स्विफ्ट 3,0

सबस्ट्रिंग i

let text = "This is the text and i want to replace something" 
let mutableAttributedString = NSMutableAttributedString(string: text) 

var searchRange = NSRange(location: 0, length: text.characters.count) 
var foundRange = NSRange() 
while searchRange.location < text.characters.count { 
    searchRange.length = text.characters.count - searchRange.location 
    foundRange = (text as NSString).range(of: "i", options: NSString.CompareOptions.caseInsensitive, range: searchRange) 
    if foundRange.location != NSNotFound { 
     // found an occurrence of the substring! do stuff here 
     searchRange.location = foundRange.location + foundRange.length 
     mutableAttributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: foundRange) 
    } 
    else { 
     // no more substring to find 
     break 
    } 
} 

//Apply 
textLabel.attributedText = mutableAttributedString; 

के सभी स्थानों और यह output-

enter image description here

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