// // NSString+Regex.m // YUMI // // Created by YUMI on 2021/9/14. // #import "NSString+Utils.h" #import #import "LoginAreaModel.h" @implementation NSString (Utils) ///是否是正确的手机号 - (BOOL)isPhoneNumber{ NSString *regex =@"^((1[3-9][0-9])|(147)|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"; NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; return [pred evaluateWithObject:self]; } ///MD5加密 - (NSString *)MD5String { const char *cstr = [self UTF8String]; unsigned char result[16]; CC_MD5(cstr, (CC_LONG)strlen(cstr), result); return [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15] ]; } + (BOOL)versionCompareOldStr:(NSString *)first andNewStr: (NSString *)second{ if ([first compare:second options:NSNumericSearch] == NSOrderedAscending){ return NO; }else if ([first compare:second options:NSNumericSearch] == NSOrderedSame){ return YES; }else{ return YES; } } +(NSString *)getDealTenNumWithString:(NSString *)string{ if (string.floatValue < 100000) { return [NSString stringWithFormat:@"%@", string]; } NSDecimalNumber *numberA = [NSDecimalNumber decimalNumberWithString:string]; NSDecimalNumber *numberB = [NSDecimalNumber decimalNumberWithString:@"1000"]; //NSDecimalNumberBehaviors对象的创建 参数 1.RoundingMode 一个取舍枚举值 2.scale 处理范围 3.raiseOnExactness 精确出现异常是否抛出原因 4.raiseOnOverflow 上溢出是否抛出原因 4.raiseOnUnderflow 下溢出是否抛出原因 5.raiseOnDivideByZero 除以0是否抛出原因。 NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; /// 这里不仅包含Multiply还有加 减 乘。 NSDecimalNumber *numResult = [numberA decimalNumberByDividingBy:numberB withBehavior:roundingBehavior]; NSString *strResult = [numResult stringValue]; return [NSString stringWithFormat:@"%@k", strResult]; } ///数字转化为万 + (NSString *)getDealNumWithString:(NSString *)string{ if (string.floatValue < 10000) { return [NSString stringWithFormat:@"%@", string]; } NSDecimalNumber *numberA = [NSDecimalNumber decimalNumberWithString:string]; NSDecimalNumber *numberB = [NSDecimalNumber decimalNumberWithString:@"10000"]; //NSDecimalNumberBehaviors对象的创建 参数 1.RoundingMode 一个取舍枚举值 2.scale 处理范围 3.raiseOnExactness 精确出现异常是否抛出原因 4.raiseOnOverflow 上溢出是否抛出原因 4.raiseOnUnderflow 下溢出是否抛出原因 5.raiseOnDivideByZero 除以0是否抛出原因。 NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; /// 这里不仅包含Multiply还有加 减 乘。 NSDecimalNumber *numResult = [numberA decimalNumberByDividingBy:numberB withBehavior:roundingBehavior]; NSString *strResult = [numResult stringValue]; return [NSString stringWithFormat:YMLocalizedString(@"NSString_Utils4"), strResult]; } + (NSString *)formatNumberToKOrM:(NSString *)string { // 定义数值单位 NSDecimalNumber *thousand = [NSDecimalNumber decimalNumberWithString:@"1000"]; NSDecimalNumber *nine = [NSDecimalNumber decimalNumberWithString:@"9999"]; NSDecimalNumber *million = [NSDecimalNumber decimalNumberWithString:@"1000000"]; NSDecimalNumber *billion = [NSDecimalNumber decimalNumberWithString:@"1000000000"]; NSDecimalNumber *trillion = [NSDecimalNumber decimalNumberWithString:@"1000000000000"]; // 创建 NSDecimalNumber 对象 NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:string]; // 判断数值范围并处理 if ([number compare:nine] == NSOrderedAscending) { // 小于 10000,直接返回原始值 return [NSString stringWithFormat:@"%@", string]; } else if ([number compare:nine] != NSOrderedAscending && [number compare:million] == NSOrderedAscending) { // 10000 到 9999999,用K表示 NSDecimalNumber *result = [number decimalNumberByDividingBy:thousand]; return [self formatResult:result withUnit:@"K"];//[NSString stringWithFormat:@"%.1fK", result.doubleValue]; } else if ([number compare:million] != NSOrderedAscending && [number compare:billion] == NSOrderedAscending) { // 超过 1000000,用M表示 NSDecimalNumber *result = [number decimalNumberByDividingBy:million]; return [self formatResult:result withUnit:@"M"];//[NSString stringWithFormat:@"%.1fM", result.doubleValue]; } else if ([number compare:billion] != NSOrderedAscending && [number compare:trillion] == NSOrderedAscending) { // 超过十亿,用 B 表示 NSDecimalNumber *result = [number decimalNumberByDividingBy:billion]; return [self formatResult:result withUnit:@"B"]; } else { // 超过一万亿,可以继续增加更高单位 NSDecimalNumber *result = [number decimalNumberByDividingBy:trillion]; return [self formatResult:result withUnit:@"T"]; // T 表示万亿 (Trillion) } } + (NSString *)formatNumberToKOrM_NoRounding:(NSString *)string { // 定义数值单位 NSDecimalNumber *thousand = [NSDecimalNumber decimalNumberWithString:@"1000"]; NSDecimalNumber *nine = [NSDecimalNumber decimalNumberWithString:@"9999"]; NSDecimalNumber *million = [NSDecimalNumber decimalNumberWithString:@"1000000"]; NSDecimalNumber *billion = [NSDecimalNumber decimalNumberWithString:@"1000000000"]; NSDecimalNumber *trillion = [NSDecimalNumber decimalNumberWithString:@"1000000000000"]; // 创建 NSDecimalNumber 对象 NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:string]; // 判断数值范围并处理 if ([number compare:nine] == NSOrderedAscending) { // 小于 10000,直接返回原始值 return [NSString stringWithFormat:@"%@", string]; } else if ([number compare:nine] != NSOrderedAscending && [number compare:million] == NSOrderedAscending) { // 10000 到 9999999,用K表示 NSDecimalNumber *result = [number decimalNumberByDividingBy:thousand]; return [self truncateDecimal:result withUnit:@"K"]; } else if ([number compare:million] != NSOrderedAscending && [number compare:billion] == NSOrderedAscending) { // 超过 1000000,用M表示 NSDecimalNumber *result = [number decimalNumberByDividingBy:million]; return [self truncateDecimal:result withUnit:@"M"]; } else if ([number compare:billion] != NSOrderedAscending && [number compare:trillion] == NSOrderedAscending) { // 超过十亿,用 B 表示 NSDecimalNumber *result = [number decimalNumberByDividingBy:billion]; return [self truncateDecimal:result withUnit:@"B"]; } else { // 超过一万亿,可以继续增加更高单位 NSDecimalNumber *result = [number decimalNumberByDividingBy:trillion]; return [self truncateDecimal:result withUnit:@"T"]; // T 表示万亿 (Trillion) } } // 格式化并截断小数位 + (NSString *)truncateDecimal:(NSDecimalNumber *)decimal withUnit:(NSString *)unit { // 获取字符串形式的结果,并截断到一位小数 NSString *decimalString = decimal.stringValue; NSArray *components = [decimalString componentsSeparatedByString:@"."]; NSString *integerPart = components.firstObject; NSString *decimalPart = components.count > 1 ? components[1] : @""; if (decimalPart.length > 1) { decimalPart = [decimalPart substringToIndex:1]; // 截断到一位小数 } if (decimalPart.length == 0 || [decimalPart isEqualToString:@"0"]) { // 如果小数部分为空或为 0,只返回整数部分 return [NSString stringWithFormat:@"%@%@", integerPart, unit]; } else { // 返回截断后的结果 return [NSString stringWithFormat:@"%@.%@%@", integerPart, decimalPart, unit]; } } + (NSString *)formatResult:(NSDecimalNumber *)result withUnit:(NSString *)unit { // 将 NSDecimalNumber 转为浮点数 CGFloat floatValue = result.floatValue; // 格式化字符串,保留两位小数 NSString *formattedString = [NSString stringWithFormat:@"%.2f", floatValue]; // 移除多余的 .00 或 .0 if ([formattedString hasSuffix:@".00"]) { formattedString = [formattedString substringToIndex:formattedString.length - 3]; // 移除 ".00" } else if ([formattedString hasSuffix:@".0"]) { formattedString = [formattedString substringToIndex:formattedString.length - 2]; // 移除 ".0" } return [NSString stringWithFormat:@"%@%@", formattedString, unit]; } + (NSString *)stringWithTimeStamp:(NSString *)timeStamp { // 转为秒为单位 NSTimeInterval second = timeStamp.longLongValue / 1000; NSDate *date = [NSDate dateWithTimeIntervalSince1970:second]; //把字符串转为NSdate NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // 时间 10点10分 NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init]; [timeFormatter setDateFormat:@"HH:mm"]; // 日期 2月18号 NSDateFormatter *dayFormatter = [[NSDateFormatter alloc] init]; [dayFormatter setDateFormat:YMLocalizedString(@"NSString_Utils0")]; // 日期 年月日 NSDateFormatter *yearFormatter = [[NSDateFormatter alloc] init]; [yearFormatter setDateFormat:YMLocalizedString(@"NSString_Utils1")]; //得到与当前时间差 NSTimeInterval timeInterval = [date timeIntervalSinceNow]; timeInterval = -timeInterval; long temp = 0; NSString *result; BOOL isSameDay = [[NSCalendar currentCalendar] isDateInToday:date]; // 是否是同一天 // A. 当天,且 timeInterval < 1分钟,显示“刚刚”; if (timeInterval < 60) { return [NSString stringWithFormat:@"%@", YMLocalizedString(@"NSString_Utils2")]; // B. 当天,且1分钟≤ timeInterval <60分钟,显示“n分钟前”; } else if((temp = timeInterval/60) < 60){ return [NSString stringWithFormat:YMLocalizedString(@"NSString_Utils3"),temp]; // C. 当天,且n≥60分钟,显示“xx:xx”; } else if((temp = temp/60) < 24 && isSameDay){ return [timeFormatter stringFromDate:date]; // C. 非当天,且n≥60分钟,显示“xx:xx”; } else if((temp = temp/60) < 24 && !isSameDay){ return [dayFormatter stringFromDate:date]; // D. 跨天,且未跨年,显示“mm-dd”; } else if((temp = temp/30) < 30){ return [dayFormatter stringFromDate:date]; } else { // E. 跨年,显示“yyyy-mm-dd”; return [yearFormatter stringFromDate:date]; } return result; } + (NSString *)calculateConstellationWithMonth:(long)time { NSString *astroString = YMLocalizedString(@"XPMineHeadView0"); NSString *astroFormat = @"102123444543"; NSString *result; NSInteger month = [NSString getMonth:time]; NSInteger day = [NSString getDay:time]; if (month<1 || month>12 || day<1 || day>31){ return YMLocalizedString(@"XPMineHeadView1"); } if(month==2 && day>29) { return YMLocalizedString(@"XPMineHeadView2"); }else if(month==4 || month==6 || month==9 || month==11) { if (day>30) { return YMLocalizedString(@"XPMineHeadView3"); } } result=[NSString stringWithFormat:@"%@",[astroString substringWithRange:NSMakeRange(month*2-(day < [[astroFormat substringWithRange:NSMakeRange((month-1), 1)] intValue] - (-19))*2,2)]]; return [NSString stringWithFormat:YMLocalizedString(@"XPMineHeadView6"),result]; } ///通过生日获取星座图片 + (NSString *)getCalculateConstellationImageWithMonth:(long)time{ NSString *astroString = YMLocalizedString(@"XPMineHeadView0"); NSString *astroFormat = @"102123444543"; NSString *result; NSInteger month = [self getMonth:time]; NSInteger day = [self getDay:time]; if (month<1 || month>12 || day<1 || day>31){ return @""; } if(month==2 && day>29) { return @""; }else if(month==4 || month==6 || month==9 || month==11) { if (day>30) { return @""; } } result=[NSString stringWithFormat:@"%@",[astroString substringWithRange:NSMakeRange(month*2-(day < [[astroFormat substringWithRange:NSMakeRange((month-1), 1)] intValue] - (-19))*2,2)]]; NSDictionary *starDic = @{YMLocalizedString(@"XPMineHeadView9"):@"pi_capricorn",YMLocalizedString(@"XPMineHeadView10"):@"pi_water_bottle",YMLocalizedString(@"XPMineHeadView11"):@"pi_pisces",YMLocalizedString(@"XPMineHeadView12"):@"pi_aries",YMLocalizedString(@"XPMineHeadView13"):@"pi_taurus",YMLocalizedString(@"XPMineHeadView14"):@"pi_gemini",YMLocalizedString(@"XPMineHeadView15"):@"pi_cancer",YMLocalizedString(@"XPMineHeadView16"):@"pi_lion",YMLocalizedString(@"XPMineHeadView17"):@"pi_virgin",YMLocalizedString(@"XPMineHeadView18"):@"pi_libra",YMLocalizedString(@"XPMineHeadView19"):@"pi_scorpion",YMLocalizedString(@"XPMineHeadView20"):@"pi_shooter"}; return starDic[result]; } ///通过生日获取星座 + (NSString *)getCalculateConstellationTextWithMonth:(long)time{ NSString *astroString = YMLocalizedString(@"XPMineHeadView0"); NSString *astroFormat = @"102123444543"; NSString *result; NSInteger month = [self getMonth:time]; NSInteger day = [self getDay:time]; if (month<1 || month>12 || day<1 || day>31){ return @""; } if(month==2 && day>29) { return @""; }else if(month==4 || month==6 || month==9 || month==11) { if (day>30) { return @""; } } result=[NSString stringWithFormat:@"%@",[astroString substringWithRange:NSMakeRange(month*2-(day < [[astroFormat substringWithRange:NSMakeRange((month-1), 1)] intValue] - (-19))*2,2)]]; return result; } +(NSInteger) getMonth:(long )time { NSDate *date = [NSDate dateWithTimeIntervalSince1970:time/1000]; NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* components = [calendar components:NSCalendarUnitMonth fromDate:date]; NSInteger month = components.month; return month; } + (NSInteger) getDay:(long) time { NSDate *date = [NSDate dateWithTimeIntervalSince1970:time/1000]; NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* components = [calendar components:NSCalendarUnitDay fromDate:date]; NSInteger day = components.day; return day; } +(NSString *)getAgeWithBirth:(long)birth{ if (birth == 0) { return @" "; } NSDateComponents *components1 = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate dateWithTimeIntervalSince1970:birth/1000]]; NSInteger brithDateYear = [components1 year]; NSInteger brithDateDay = [components1 day]; NSInteger brithDateMonth = [components1 month]; // 获取系统当前 年月日 NSDateComponents *components2 = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]]; NSInteger currentDateYear = [components2 year]; NSInteger currentDateDay = [components2 day]; NSInteger currentDateMonth = [components2 month]; // 计算年龄 NSInteger iAge = currentDateYear - brithDateYear - 1; if ((currentDateMonth > brithDateMonth) || (currentDateMonth == brithDateMonth && currentDateDay >= brithDateDay)) { iAge++; } return [NSString stringWithFormat:@" %ld ", iAge]; } ///得到区号 +(NSString *)getCountryCode{ // 获取文件路径 NSString *path = [[NSBundle mainBundle] pathForResource:@"pi_area_info" ofType:@"json"]; // 将文件数据化 NSData *data = [[NSData alloc] initWithContentsOfFile:path]; // 对数据进行JSON格式化并返回字典形式 NSError *error = nil; NSDictionary *codeData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error]; if (error) { // NSLog(@"JSON Parsing Error: %@", error.localizedDescription); } NSArray *codeList = [LoginAreaModel modelsWithArray:codeData[@"RECORDS"]]; NSString *mccCode = [YYUtility getMobileCountryCode]; NSString *countryCode = @""; if([mccCode isEqualToString:@"65535"]) { return @"+886"; } for (LoginAreaModel *obj in codeList) { if([mccCode isEqualToString:obj.mcc]){ countryCode = obj.code; break; } } if(countryCode.length == 0) { return @"+886"; } return [NSString stringWithFormat:@"+%@",countryCode]; } +(NSString *)createUUID{ CFUUIDRef uuid; CFStringRef uuidText; uuid = CFUUIDCreate(NULL); uuidText = CFUUIDCreateString(NULL, uuid); NSString *time = [NSDate getNowTimeTimestamp]; NSString *result = [NSString stringWithFormat:@"%@%@",uuidText,time]; return [result MD5String]; } + (BOOL)isEmpty:(NSString *)string { if (string == nil || [string isKindOfClass:[NSNull class]]) { return YES; } NSString *trimmedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; return trimmedString.length == 0; } - (NSString *)pureURLString { NSString *encodingUrl = [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet]; return encodingUrl;//[self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; // NSURLComponents *components = [NSURLComponents componentsWithString:self]; // components.query = [components.query stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; // return components.string; } + (NSString *)stringByRemovingRedundantZeros:(NSString *)string { // 1. 检查输入是否有效 if (!string || string.length == 0) { return string; } // 2. 检查字符串是否包含小数点 if ([string rangeOfString:@"."].location == NSNotFound) { return string; // 没有小数点,直接返回原始字符串 } // 3. 使用NSDecimalNumber进行精确的数值处理 NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithString:string]; if ([decimalNumber isEqual:[NSDecimalNumber notANumber]]) { return string; // 转换失败,返回原始字符串 } // 4. 设置四舍五入处理器,精确到小数点后2位 NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; // 5. 执行四舍五入操作 NSDecimalNumber *roundedNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:handler]; // 6. 将四舍五入后的数字转换为字符串 NSString *formattedString = [roundedNumber stringValue]; // 7. 分离整数部分和小数部分 NSArray *components = [formattedString componentsSeparatedByString:@"."]; NSString *integerPart = components[0]; // 8. 如果没有小数部分,直接返回整数部分 if (components.count < 2) { return integerPart; } NSString *fractionalPart = components[1]; // 9. 如果小数部分为空,返回整数部分 if (fractionalPart.length == 0) { return integerPart; } // 10. 移除小数部分末尾的0 NSUInteger lastNonZeroIndex = NSNotFound; for (NSInteger i = fractionalPart.length - 1; i >= 0; i--) { if ([fractionalPart characterAtIndex:i] != '0') { lastNonZeroIndex = i; break; } } // 11. 如果小数部分全是0,返回整数部分 if (lastNonZeroIndex == NSNotFound) { return integerPart; } else { // 12. 组合整数部分和修剪后的小数部分 NSString *trimmedFraction = [fractionalPart substringToIndex:lastNonZeroIndex + 1]; return [NSString stringWithFormat:@"%@.%@", integerPart, trimmedFraction]; } } //+ (NSString *)stringByRemovingRedundantZeros:(NSString *)string { // if (![string containsString:@"."]) { // return string; // 不包含小數點,直接返回 // } // // // 將字串分割成整數部分和小數部分 // NSArray *components = [string componentsSeparatedByString:@"."]; // if (components.count > 2) { // return string; // 包含多個小數點,不處理直接返回 (或者您可以考慮拋出錯誤) // } // // NSString *integerPart = components[0]; // NSString *fractionalPart = components.count > 1 ? components[1] : @""; // // if (fractionalPart.length == 0) { // return integerPart; // 沒有小數部分,直接返回整數部分 // } // // // 從後向前移除小數部分末尾的 0 // NSInteger lastNonZeroIndex = -1; // for (NSInteger i = fractionalPart.length - 1; i >= 0; i--) { // if ([fractionalPart characterAtIndex:i] != '0') { // lastNonZeroIndex = i; // break; // } // } // // if (lastNonZeroIndex == -1) { // return integerPart; // 小數部分全是 0,返回整數部分 // } else { // // 截取到最後一個非零數字 // NSString *trimmedFractionalPart = [fractionalPart substringToIndex:lastNonZeroIndex + 1]; // return [NSString stringWithFormat:@"%@.%@", integerPart, trimmedFractionalPart]; // } //} + (NSString *)trimString:(NSString *)input lengthLimit:(NSInteger)limit { if (input.length <= limit) { return input; } else { NSString *trimmedString = [input substringToIndex:limit]; return [trimmedString stringByAppendingString:@"..."]; } } /// 判断 URL 是否为有效的图片格式 + (BOOL)isValidImageURL:(NSString *)url { if ([NSString isEmpty:url]) { return NO; } NSString *lowercaseURL = url.lowercaseString; NSArray *imageExtensions = @[@"png", @"jpg", @"jpeg", @"gif", @"webp", @"bmp", @"svg"]; for (NSString *extension in imageExtensions) { if ([lowercaseURL hasSuffix:extension]) { return YES; } } return NO; } /// 检查字符串是否为图片格式(通过扩展名判断) + (BOOL)isImageFormat:(NSString *)url { if ([NSString isEmpty:url]) { return NO; } NSString *lowercaseURL = url.lowercaseString; NSArray *imageExtensions = @[@".png", @".jpg", @".jpeg", @".gif", @".webp", @".bmp", @".svg"]; for (NSString *extension in imageExtensions) { if ([lowercaseURL hasSuffix:extension]) { return YES; } } return NO; } @end