[英]How to split NSString where two or more whitespace characters are found?
給定的字符串輸入:
@"bonus pay savings 2.69 F";
@"brick and mortar 0.15-B";
所需的輸出字符串:
[@"bonus pay savings", @"2.69 F"];
[@"brick and mortar", @"0.15-B"];
我嘗試了這種方法:
NSString * str = @"bonus pay savings 2.69 F";
NSArray * arr = [str componentsSeparatedByString:@" "];
NSLog(@"Array values are : %@",arr);
但是我的方法的缺點是我使用3個空格作為分隔符,而空格的數量可以變化。 如何做到這一點? 謝謝。
使用正則表達式的簡單解決方案。
它用隨機UUID字符串替換所有出現的2個或更多( {2,}
)空格字符( \\\\s
)。 然后,它將字符串按該UUID字符串拆分。
NSString *separator = [NSUUID UUID].UUIDString;
NSString *string = @"bonus pay savings 2.69 F";
NSString *collapsedString = [string stringByReplacingOccurrencesOfString:@"\\s{2,}"
withString:separator
options:NSRegularExpressionSearch
range:NSMakeRange(0, [string length])];
NSArray *output = [collapsedString componentsSeparatedByString:separator];
NSLog(@"%@", output);
您可以使用NSRegularExpression
分割字符串。 讓我們在NSString
上創建一個類別:
NSString+asdiu.h
@interface NSString (asdiu)
- (NSArray<NSString *> *)componentsSeparatedByRegularExpressionPattern:(NSString *)pattern error:(NSError **)errorOut;
@end
NSString+asdiu.m
@implementation NSString (asdiu)
- (NSArray<NSString *> *)componentsSeparatedByRegularExpressionPattern:(NSString *)pattern error:(NSError **)errorOut {
NSRegularExpression *rex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:errorOut];
if (rex == nil) { return nil; }
NSMutableArray<NSString *> *components = [NSMutableArray new];
__block NSUInteger start = 0;
[rex enumerateMatchesInString:self options:0 range:NSMakeRange(0, self.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
NSRange separatorRange = result.range;
NSRange componentRange = NSMakeRange(start, separatorRange.location - start);
[components addObject:[self substringWithRange:componentRange]];
start = NSMaxRange(separatorRange);
}];
[components addObject:[self substringFromIndex:start]];
return components;
}
@end
您可以像這樣使用它:
NSArray<NSString *> *inputs = @[@"bonus pay savings 2.69 F", @"brick and mortar 0.15-B"];
for (NSString *input in inputs) {
NSArray<NSString *> *fields = [input componentsSeparatedByRegularExpressionPattern:@"\\s\\s+" error:nil];
NSLog(@"fields: %@", fields);
}
輸出:
2018-06-15 13:38:13.152725-0500 test[23423:1386429] fields: (
"bonus pay savings",
"2.69 F"
)
2018-06-15 13:38:13.153140-0500 test[23423:1386429] fields: (
"brick and mortar",
"0.15-B"
)
如果可以假設輸入字符串中只有2個字段,那么我將使用這種有限的拆分方法,該方法始終返回2個項目的數組,然后使用stringByTrimmingCharactersInSet來 “修剪”第二個項目。
@vadian和@robmayoff雙雙提供基於正則表達式(RES)好的解決辦法,在這兩種情況下的RE用於匹配的差距 ,找到在哪里打破你的字符串。 對於比較解決問題的方法,也可以使用RE來匹配您感興趣的零件,以另一種方式進行。 那里:
\S+(\h\S+)*
將與您感興趣的文本匹配,組成如下:
\S - match any non-space character, \S excludes both horizontal
(e.g. spaces, tabs) and vertical space (e.g. newlines)
\S+ - one or more non-space characters, i.e. a "word" of sorts
\h - a single horizontal space character (if you wish matches to
span lines use \s - any horizontal *or* vertical space)
\h\S+ - a space followed by a word
(\h\S+)* - zero or more space separated words
\S+(\h\S+)* - a word follow by zero or more words
通過這個簡單的正則表達式,您可以使用matchesInString:options:range:
來獲得一個NSTextCheckingResult
對象數組, NSTextCheckingResult
對象對應於您輸入中的每個匹配項。 或者您可以使用enumerateMatchesInString:options:range:usingBlock:
在每個匹配項中調用一個塊。
例如,以下是@robmayoff方法的解決方案:
@interface NSString (componentsMatchingRegularExpression)
- (NSArray<NSString *>*) componentsMatchingRegularExpression:(NSString *)pattern;
@end
@implementation NSString (componentsMatchingRegularExpression)
- (NSArray<NSString *>*) componentsMatchingRegularExpression:(NSString *)pattern
{
NSError *errorReturn;
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&errorReturn];
if (!regularExpression)
return nil;
NSMutableArray *matches = NSMutableArray.new;
[regularExpression enumerateMatchesInString:self
options:0
range:NSMakeRange(0, self.length)
usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop)
{
[matches addObject:[self substringWithRange:result.range]];
}
];
return matches.copy; // non-mutable copy
}
@end
是否匹配您希望保留或刪除的內容比較主觀,請選擇。
正則表達式對此很合適,使用它們給出的解決方案也非常合適,但是對於完成而言,您也可以使用NSScanner做到這一點,NSScanner幾乎總是比正則表達式具有更好的性能,如果您習慣使用它則非常方便需要做更復雜的文本解析。
NSString *str = @"bonus pay savings 2.69 F";
NSScanner *scanner = [NSScanner scannerWithString:str];
scanner.charactersToBeSkipped = nil; // default is to ignore whitespace
while (!scanner.isAtEnd) {
NSString *name;
NSString *value;
// scan up to two spaces, this would be the name
[scanner scanUpToString:@" " intoString:&name];
// scan the two spaces and any extra whitespace
[scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:nil];
// scan to the end of the line, this is the value
[scanner scanUpToString:@"\n" intoString:&value];
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.