Jak sprawdzić, czy NSString zaczyna się od określonego innego ciągu?

152

Próbuję sprawdzić, czy ciąg, którego będę używać jako adresu URL, zaczyna się od http. Sposób, w jaki próbuję teraz sprawdzić, wydaje się nie działać. Oto mój kod:

NSMutableString *temp = [[NSMutableString alloc] initWithString:@"http://"];
if ([businessWebsite rangeOfString:@"http"].location == NSNotFound){
    NSString *temp2 = [[NSString alloc] init];
    temp2 = businessWebsite;
    [temp appendString:temp2];
    businessWebsite = temp2;
    NSLog(@"Updated BusinessWebsite is: %@", businessWebsite);
}

[web setBusinessWebsiteUrl:businessWebsite];

Jakieś pomysły?

Obrabować
źródło

Odpowiedzi:

331

Spróbuj tego: if ([myString hasPrefix:@"http"]).

Nawiasem mówiąc, twój test powinien być != NSNotFoundzamiast == NSNotFound. Ale powiedz, że Twój adres URL to ftp://my_http_host.com/thing, będzie pasował, ale nie powinien.

Cyrille
źródło
Tak, to było to. Powinienem wcześniej zauważyć! = Rzecz, ale w końcu to hasPrefix zadziałał. Dzięki za radę, oznaczę twoją odpowiedź jako poprawną, gdy tylko mi na to pozwoli.
Rob
23

Lubię używać tej metody:

if ([[temp substringToIndex:4] isEqualToString:@"http"]) {
  //starts with http
}

lub jeszcze łatwiej:

if ([temp hasPrefix:@"http"]) {
    //do your stuff
}
JonasG
źródło
1
To też dobrze. Ten sposób jest również trochę bardziej elastyczny, dzięki za komentarz
Rob
2
Spowoduje to awarię, jeśli łańcuch tymczasowy ma mniej niż 5 znaków. Indeks zaczyna się od 0. Więc to nie jest dobra odpowiedź. W przykładzie występuje również niezgodność liczby znaków: „http” nie ma 5 znaków. Należy również wziąć pod uwagę niewrażliwość na wielkość liter.
Daniel
@Daniel Co ty w ogóle mówisz? Dlaczego 5? To nie jest tablica NSArray ... Indeks 4 to czwarty znak, a nie piąty! I czy kiedykolwiek widziałeś Http lub HTTP? Uwzględnianie wielkości liter nie ma znaczenia. Pytanie dotyczyło również sprawdzenia, czy ciąg zaczyna się od http, a nie krótszego niż 4 znaki. hasPrefix: jest lepszy, ale działa równie dobrze. Przestań
marudzić
3
@JonasG - Tak, masz rację co do zachowania substringToIndex. Należy jednak pamiętać, że indeks 4 to w rzeczywistości piąty znak; indeks 0 to pierwszy znak. Błędnie założyłem, że substringToIndex zawiera znak określony przez indeks, ale tak nie jest. Uwzględnianie wielkości liter ma znaczenie, gdy chodzi o dane wejściowe użytkownika, do czego, jak sądzę, wskazuje pytanie. Rozważ przypadek „ HTTP: // WWW ...”. Ale największym problemem jest to, że proponowane rozwiązanie zgłosi wyjątek, gdy napotka „ftp” lub łańcuch mniejszy niż 4 znaki. Metoda hasPrefix nie ma tego samego problemu.
Daniel,
6

Jeśli szukasz „http:”, prawdopodobnie będziesz potrzebować wyszukiwania bez rozróżniania wielkości liter:

NSRange prefixRange = 
    [temp rangeOfString:@"http" 
                options:(NSAnchoredSearch | NSCaseInsensitiveSearch)];
if (prefixRange.location == NSNotFound)
bobiki
źródło
2

Wersja Swift:

if line.hasPrefix("#") {
  // checks to see if a string (line) begins with the character "#"
}
Richard
źródło
Nie wiem, dlaczego głosowano w dół ... to prosty sposób na szybki sposób. Większość nowych programistów iOS prawdopodobnie będzie używać Swift od teraz, a OP nigdy nie powiedział, że proszono tylko o odpowiedzi Objective-C.
Richard
„Nie wiem, dlaczego głosowano w dół” - prawdopodobnie dlatego, że składnia jest nieprawidłowa? Powinien być if line.hasPrefix("prefix"){} `
superarts.org
1
Dziękujemy za wskazanie prostszej składni, ale umieszczenie () wokół instrukcji if nie jest złą składnią. Dla niektórych z nas, starych timerów, czyta się jaśniej i działa dokładnie tak samo. if (line.hasPrefix("#")) {}działa równie dobrze.
Richard,
-1

To jest moje rozwiązanie problemu. Usunie litery, które nie są potrzebne i nie uwzględniają wielkości liter.

    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [self generateSectionTitles];
}

-(NSArray *)generateSectionTitles {

    NSArray *alphaArray = [NSArray arrayWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z", nil];

    NSMutableArray *sectionArray = [[NSMutableArray alloc] init];

    for (NSString *character in alphaArray) {



        if ([self stringPrefix:character isInArray:self.depNameRows]) {
            [sectionArray addObject:character];
        }

    }

    return sectionArray;

}

-(BOOL)stringPrefix:(NSString *)prefix isInArray:(NSArray *)array {

    for (NSString *str in array) {

        //I needed a case insensitive search so [str hasPrefix:prefix]; would not have worked for me.
        NSRange prefixRange = [str rangeOfString:prefix options:(NSAnchoredSearch | NSCaseInsensitiveSearch)];
        if (prefixRange.location != NSNotFound) {
            return TRUE;
        }

    }

    return FALSE;

}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {

    NSInteger newRow = [self indexForFirstChar:title inArray:self.depNameRows];
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:newRow inSection:0];
    [tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];

    return index;
}

// Return the index for the location of the first item in an array that begins with a certain character
- (NSInteger)indexForFirstChar:(NSString *)character inArray:(NSArray *)array
{
    NSUInteger count = 0;
    for (NSString *str in array) {

        //I needed a case insensitive search so [str hasPrefix:prefix]; would not have worked for me.
        NSRange prefixRange = [str rangeOfString:character options:(NSAnchoredSearch | NSCaseInsensitiveSearch)];
        if (prefixRange.location != NSNotFound) {
            return count;
        }
        count++;
    }
    return 0;
}
Hackmodford
źródło