利用系统 api 来识别文本中的电话号码,地址,日期等等
可以识别的有
typedef NS_OPTIONS(uint64_t, NSTextCheckingType) { // a single type
NSTextCheckingTypeOrthography = 1ULL << 0, // language identification
NSTextCheckingTypeSpelling = 1ULL << 1, // spell checking
NSTextCheckingTypeGrammar = 1ULL << 2, // grammar checking
NSTextCheckingTypeDate = 1ULL << 3, // date/time detection
NSTextCheckingTypeAddress = 1ULL << 4, // address detection
NSTextCheckingTypeLink = 1ULL << 5, // link detection
NSTextCheckingTypeQuote = 1ULL << 6, // smart quotes
NSTextCheckingTypeDash = 1ULL << 7, // smart dashes
NSTextCheckingTypeReplacement = 1ULL << 8, // fixed replacements, such as copyright symbol for (c)
NSTextCheckingTypeCorrection = 1ULL << 9, // autocorrection
NSTextCheckingTypeRegularExpression NS_ENUM_AVAILABLE(10_7, 4_0) = 1ULL << 10, // regular expression matches
NSTextCheckingTypePhoneNumber NS_ENUM_AVAILABLE(10_7, 4_0) = 1ULL << 11, // phone number detection
NSTextCheckingTypeTransitInformation NS_ENUM_AVAILABLE(10_7, 4_0) = 1ULL << 12 // transit (e.g. flight) info detection
};
typedef uint64_t NSTextCheckingTypes; // a combination of types
NS_ENUM(NSTextCheckingTypes) {
NSTextCheckingAllSystemTypes = 0xffffffffULL, // the first 32 types are reserved
NSTextCheckingAllCustomTypes = 0xffffffffULL << 32, // clients may use the remainder for their own purposes
NSTextCheckingAllTypes = (NSTextCheckingAllSystemTypes | NSTextCheckingAllCustomTypes)
};
// 电话号码,利用正则表达式识别
- (NSArray<NSTextCheckingResult *> *)getRangesForPhoneNumbers:(NSString *)text
{
NSString *expressionString = @"((?<=\\D)|^)((1+\\d{10})|(0+\\d{2,3}-\\d{7,8}|\\d{7,8}))((?=\\D)|$)";
NSError *error;
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:expressionString options:NSRegularExpressionCaseInsensitive error:&error];
NSMutableArray *ranges = [[NSMutableArray alloc] init];
if (expression) {
[expression enumerateMatchesInString:text options:0 range:NSMakeRange(0, text.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
// result.resultType == NSTextCheckingTypeRegularExpression, need change to NSTextCheckingTypePhoneNumber;
NSString *phoneNumber = [text substringWithRange:result.range];
NSTextCheckingResult *newResult = [NSTextCheckingResult phoneNumberCheckingResultWithRange:result.range phoneNumber:phoneNumber];
[ranges addObject:newResult];
}];
}
return ranges;
}
// 所有类别
改用正则表达式 识别电话号码,超长的数字字符串也可以过滤掉
@"((?<=\D)|^)((1+\d{10})|(0+\d{2,3}-\d{7,8}|\d{7,8}))((?=\D)|$)"
- (NSArray *)getRangesForAllCheckTypes:(NSString *)text
{
NSMutableArray *rangesForPhoneNumbers = [[NSMutableArray alloc] init];;
NSError *error = nil;
NSDataDetector *detector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingAllTypes error:&error];
NSArray *matches = [detector matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
NSMutableArray *mutMatches = [matches mutableCopy];
// remove phone number,use self
NSPredicate *phoneNumberPredicate = [NSPredicate predicateWithBlock:^BOOL(NSTextCheckingResult* _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
if ([evaluatedObject isKindOfClass:[NSTextCheckingResult class]] &&
[evaluatedObject resultType] != NSTextCheckingTypePhoneNumber) {
return YES;
} else {
return NO;
}
}];
[mutMatches filterUsingPredicate:phoneNumberPredicate];
// \d{3,4}-\d{7,8}|\d{7,8}
if (self.enabledTextCheckingTypes & NSTextCheckingTypePhoneNumber) {
NSString *expressionString = @"((?<=\\D)|^)((1+\\d{10})|(0+\\d{2,3}-\\d{7,8}|\\d{7,8}))((?=\\D)|$)";
NSError *error;
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:expressionString options:NSRegularExpressionCaseInsensitive error:&error];
if (expression) {
[expression enumerateMatchesInString:text.string options:0 range:NSMakeRange(0, text.string.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
// result.resultType == NSTextCheckingTypeRegularExpression, need change to NSTextCheckingTypePhoneNumber;
NSString *phoneNumber = [text.string substringWithRange:result.range];
NSTextCheckingResult *newResult = [NSTextCheckingResult phoneNumberCheckingResultWithRange:result.range phoneNumber:phoneNumber];
[mutMatches addObject:newResult];
}];
}
}
if (mutMatches.count == 0) {
return NO;
}
for (NSTextCheckingResult *match in mutMatches)
{
NSRange matchRange = [match range];
NSString *matchString = [text substringWithRange:matchRange];
[rangesForPhoneNumbers addObject:@{
@"linkType" : @([match resultType]),
@"range" : [NSValue valueWithRange:matchRange],
@"link" : matchString
}];
}
return rangesForPhoneNumbers;
}