gpt4 book ai didi

objective-c - 24hr至12hr时间转换,将字符插入字符串

转载 作者:行者123 更新时间:2023-12-03 17:44:45 24 4
gpt4 key购买 nike

这是我的问题here的第二个问题,但建议将问题分开以得到更好的回答。

我有单独的数据行,如下所示,它们分别传递给函数。

Mon-Wed 930-1700 Thu 900-1700 Fri 930-1700  
Mon-Wed 930-1700 Thu 900-1700 Fri 930-1700 Sat 900-1200, Home Lending Sat 900-1600
Mon-Thu 900-1600, Fri 900-1700


并需要例如以下内容阅读:

Mon-Wed 9:30am-5:00pm;Thu 9:00am-5:00pm;Fri 9:30am-5:00pm;Sat 9:00am-12:00pm, Home Lending Sat 9:00am-4:00pm


我需要将时间转换为12小时,这相对容易,例如

if (time > 1200) {  
time = time - 1200
//add the pm and the colon :
} else {
//add the am and the colon :
}


我的问题是,我该如何:
-首先寻找数字。
-将它们拉出并转换为int以执行计算(我认为使用intValue)。
-进行计算,然后将其重新插入字符串的相同位置,包括am / pm和冒号。

我一直在使用RegexKitLite中的regex,但是我如何记起将其重新插入字符串的位置以及如何删除字符串中已经存在的内容来替换它呢?例如1700。我假设使用MutableStrings,但需要一些帮助。

这是我一直在努力的一些代码,但不介意是否有更简单的解决方案来解决这个问题……

NSString *regexString = @"(\\s|-?)(\\d{3,4})(;?|\\s?|-?)";

NSRange matchedRange = NSMakeRange(NSNotFound,NSNotFound);

//loop while we haven't fixed all times in the string
while (!matchedRange.length == 0) {

matchedRange = [openingHoursString rangeOfRegex:regexString capture: 2];

if (!matchedRange.length == 0) {

NSString *digits = [openingHoursStrinig substringWithRange: matchedRange];
NSLog(@"digits string: %@", digits);

//do calculations and add colon to digits string and reinsert to openingHoursString
}
}

最佳答案

一种方法是通过RegexKitLites块支持:

NSString *string = @"Mon-Wed 930-1700 Thu 900-1700 Fri 930-1700\nMon-Wed 930-1700 Thu 900-1700 Fri 930-1700 Sat 900-1200, Home Lending Sat 900-1600\nMon-Thu 900-1600, Fri 900-1700";

NSString *replaced = [string stringByReplacingOccurrencesOfRegex:@"(?<=[[:Pattern_Syntax:][:White_Space:]]|\\A)(\\d{1,2})(\\d{2,2})(?=[[:Pattern_Syntax:][:White_Space:]]|\\z)" usingBlock:^NSString *(NSInteger captureCount, NSString * const capturedStrings[captureCount], const NSRange capturedRanges[captureCount], volatile BOOL * const stop) {
NSInteger hour = [capturedStrings[1] integerValue];
NSString *amOrPMString = @"am";
if(hour >= 12) { amOrPMString = @"pm"; if(hour > 12) { hour -= 12; } }

return([NSString stringWithFormat:@"%d:%@%@", hour, capturedStrings[2], amOrPMString]);
}];

NSLog(@"Replaced:\n%@", replaced);


运行时,输出以下内容:

2010-07-10 17:42:10.650 RegexKitLite[26086:a0f] Replaced:
Mon-Wed 9:30am-5:00pm Thu 9:00am-5:00pm Fri 9:30am-5:00pm
Mon-Wed 9:30am-5:00pm Thu 9:00am-5:00pm Fri 9:30am-5:00pm Sat 9:00am-12:00pm, Home Lending Sat 9:00am-4:00pm
Mon-Thu 9:00am-4:00pm, Fri 9:00am-5:00pm


编辑2010/07/11-根据OP的请求添加信息。

该示例中使用的正则表达式的解释如下(细分为四个最逻辑的块)

1: (?<=[[:Pattern_Syntax:][:White_Space:]]|\A)
2: (\d{1,2})
3: (\d{2,2})
4: (?=[[:Pattern_Syntax:][:White_Space:]]|\z)


第1部分

序列 (?<= ... )的意思是“后向断言”,或者在散文中,它大致翻译为“如果正则表达式的下一部分(在本例中为#2),则紧接在前面的文本#2必须由括号中的正则表达式匹配”。

在这种情况下,“用这些括号括起来的”正则表达式为 [[:Pattern_Syntax:][:White_Space:]]|\A。此正则表达式在粗略的散文中说“匹配具有Pattern_Syntax或White_Space或 \A的Unicode属性的字符集中的任何字符,即 Match at the beginning of the input. Differs from ^ in that \A will not match after a new-line within the input.Pattern_SyntaxWhite_Space的字符是诸如''(空格),'\ t'(制表符),换行符等字符。 Pattern_Syntax是'-',', ','%'等

第2部分和第3部分

这些部分非常明显。 \d匹配一个“数字”字符,例如'0'..'9',并且 {x,y}表示“匹配至少 x,但不超过 y次”。

第4部分

第4部分与第1部分基本相同,不同之处在于它使用了 (?=形式的“先行断言”,并且希望从第1部分的解释上下文中可以明显看出其含义。另一个区别是使用了 \z,表示“如果当前位置在输入的末尾则匹配。”。

为什么需要 \A\z?如果时间是字符串中的第一位,或者由于 []要匹配的字符集而导致的字符串中的最后一位,则时间不包括“或者如果要匹配的文本的开头或末尾不包含任何字符” ”。例如,OP的示例字符串以 ..., Fri 900-1700结尾。如果没有 |\z,则正则表达式将与最后一个 1700不匹配。

为什么需要第1部分和第4部分?它们可能不是,取决于要匹配的文本字符串的确切格式。由于我不能过多地谈论输入字符串的格式,因此我试图使其变得“相当健壮”,并且可以承受各种合理的输入。绝对有多种方法可以做到这一点。

块做什么

每次匹配正则表达式时,都会调用 ^{}块。有关匹配内容的详细信息作为参数传递给块。然后,Block返回一个新字符串,该字符串用于替换正则表达式匹配的所有文本。重复此过程,直到字符串中不再有正则表达式匹配为止。

为了清楚起见,原始字符串仅“匹配一次”。例如,给定的正则表达式实质上匹配任何形式为“ NNN”或“ NNNN”的“数字”。对于每个匹配项,都会调用Block,然后在最后一个匹配项之后的下一个字符处搜索原始字符串中的下一个匹配项。它不会以任何方式“返回”或“重新开始”。

原始字符串不做任何修改。而是构造了一个全新的字符串。它由“匹配之间的文本”和块返回的替换字符串一点一点地建立起来。完成所有替换后,将返回此字符串。

编辑2010/07/12-为每个OP的(附加)请求添加一些其他信息。

问:如果我对输入格式的一致性更有信心(例如Day-DaySpaceTime或DaySpaceTime),我是否可以使用这样的正则表达式? (\ s |-?)(\ d {1,2})(\ d {2,2})(;? | \ s?|-?)。

答:如果您对输入格式更有信心,则可以肯定地更改正则表达式。例如,如果您“绝对肯定”输入将始终采用 nNNN-nNNN的形式(其中小写的 n表示“可选数字”,如 900-1730 vs 1100-1915)对于“时间”,可以将代码更改为:

NSString *string = @"Mon-Wed 930-1700 Thu 900-1700 Fri 930-1700\nMon-Wed 930-1700 Thu 900-1700 Fri 930-1700 Sat 900-1200, Home Lending Sat 900-1600\nMon-Thu 900-1600, Fri 900-1700";

NSString *replaced = [string stringByReplacingOccurrencesOfRegex:@"\\b(\\d{1,2})(\\d{2,2})\\-(\\d{1,2})(\\d{2,2})\\b" usingBlock:^NSString *(NSInteger captureCount, NSString * const capturedStrings[captureCount], const NSRange capturedRanges[captureCount], volatile BOOL * const stop) {
NSInteger firstHour = [capturedStrings[1] integerValue], secondHour = [capturedStrings[3] integerValue];
NSString *firstAMorPMString = @"am", *secondAMorPMString = @"am";

if(firstHour >= 12) { firstAMorPMString = @"pm"; if(firstHour > 12) { firstHour -= 12; } }
if(secondHour >= 12) { secondAMorPMString = @"pm"; if(secondHour > 12) { secondHour -= 12; } }
if(firstHour == 0) { firstHour = 12; }
if(secondHour == 0) { secondHour = 12; }

return([NSString stringWithFormat:@"%d:%@%@-%d:%@%@", firstHour, capturedStrings[2], firstAMorPMString, secondHour, capturedStrings[4], secondAMorPMString]);
}];

NSLog(@"Replaced:\n%@", replaced);


本示例将两个“时间”作为单个块进行处理。正则表达式开头和结尾处的 \b表示 Match if the current position is a word boundary。这样可以防止它匹配 abc123-456def之类的东西。在原始示例中,它是更复杂的 [[:Pattern_Syntax:][:White_Space:]]内容的一种简单形式,但不一定表示完全相同的内容(尽管“在大多数情况下,它非常接近”)。

将两个时间作为单个块进行匹配的另一个优点是,它减少了仅匹配一次就可能发生的潜在“错误匹配”次数。例如,第一个示例会将“ Home econ 101”的“注释”变成“ Home econ 1:01 am”,这可能不是您想要的。 :)

我还修改了该示例,以使“军事24小时制”为“ 000”表示“ 12:00 am”,因此它假定解析的时间值始终为24小时军用时间格式。

Q也是(?<= ...)后面的RegexKitLite语法部分还是标准正则表达式?

A It是ICU库接受的regex语法的一部分(RegexKitLite用于执行实际的正则表达式匹配)。尽管 (?<=...)(?=...)都被“大多数”正则表达式引擎接受,但它们本身没有“标准正则表达式语法”。

问:抱歉,在您的正则表达式中,您有四组(),是否表示存在一个captureStrings [0],capturedStrings [1],capturedStrings [2],capturedStrings [3]?

答: (?<=...)(?=...)模式是所谓的“零宽度断言”。它们实际上并不对正则表达式“捕获”的文本有帮助,但是必须匹配给定的文本才能使整个正则表达式“匹配”。上一句话中的“已捕获”和“匹配”之间的区别在于,“已捕获”消耗了匹配的输入部分,而“已匹配”则没有。这使您可以创建诸如 (\d+)(?=,)之类的正则表达式,这意味着“匹配并'捕获'一个或多个数字,必须在其后加上',',但不捕获结尾的逗号”。先行查找和后向查找绝对是正则表达式的高级,非新颖特征,很难在此类简短文章中充分解释。

但是,特别需要注意的是,与 (?<=...)不同, (?=...)(\d{1,2})(\d{2,2})都不算作“捕获”。即使总共有四个括号组,原始示例中的完整正则表达式也仅包含两个捕获。

关于objective-c - 24hr至12hr时间转换,将字符插入字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3218375/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com