在最近的开发中,我遇到了一个小问题:需要从类似“今天 时:分”或“今天”这样的字符串中提取时间信息。如果时间精确到分钟,就返回该具体时间;如果只是“今天”,默认设置为“00:00”,即当天的 0 点。
一开始,我考虑了两种解决方式:一种是通过正则表达式,另一种方式是通过字符串的操作,这里更适合哪一种方式呢?
示例代码如下所示
// 正则表达式
const matchToday = input.match(/^今天(?: (\d{1,2}:\d{2}))?$/);
if (matchToday) {
const time = matchToday[1] || '00:00'; // 如果没有时间,则为00:00
return new Date(`${year}-${month}-${day} ${time}:00`).getTime();
}
// 利用字符串的分割和简单的条件判断
if (input.startsWith('今天')) {
const timePart = input.replace('今天', '').trim();
const time = timePart || '00:00'; // 如果没有时间,则为00:00
return new Date(`${year}-${month}-${day} ${time}:00`).getTime();
}
代码分析
在选择使用 正则表达式 还是 字符串处理 的问题上,我们需要考虑以下几个方面:容错性、效率以及代码的易维护性。
1、容错性
正则表达式的容错性更好,尤其在处理格式不规范的输入时,能够更好地避免出错。
正则表达式:
-
正则表达式可以精确地控制要匹配的字符串格式,比如处理日期格式时,可以对数字、符号等进行精准的匹配。
-
容错性较好,特别是在处理复杂字符串时(如用户输入不符合预期的时间格式),正则能够更严格地匹配,避免误处理。
-
但正则也有局限性,尤其当需要匹配多种复杂场景时,表达式可能变得过于复杂,不易于维护。
字符串处理:
-
字符串处理的容错性较低,尤其是依赖直接的
replace
或split
操作时,如果输入不规范,容易出错。例如,在解析日期格式时,字符串操作可能会忽略一些边缘情况(如不完整的时间格式或异常空格等),要考虑的情况比较多,如果稍微疏忽就可能出现bug。 -
如果我们只是处理一些简单的字符串时,比如开头说到的这个问题,这时候字符串处理方式更为直接和高效。输入的字符串是固定的,格式也是固定的。
2、效率
字符串处理在性能上通常会优于正则表达式,尤其是在处理大量简单数据时。
正则表达式:
-
正则表达式在处理小规模的字符串时效率较高,因为它是专门为模式匹配而优化的。然而,当涉及到大量复杂的规则或大规模文本时,正则表达式的性能可能会下降。
-
在极端情况下,过于复杂的正则表达式会出现性能瓶颈。
字符串处理:
-
字符串处理操作(如
replace
、split
、trim
等)通常比正则表达式处理简单的操作更高效。对于单纯的字符串替换和分割,字符串方法可能比正则更快,尤其是在处理大量输入时。 -
按照我当前这个需求来说,字符串的数据结构是固定的,而且解析起来也比较简单,这时候字符串处理效率会比正则表达式更好
3、代码可读性与维护性
对于当前场景,字符串处理的可读性和可维护性比正则表达式好,尤其在处理固定格式数据时。
正则表达式:
-
正则表达式的语法对于复杂的匹配规则很强大,但可读性较差。尤其是很多人对这个正则匹配不是那么熟悉,后续如果出现问题需要修改的话,可能不是那么容易定位到问题。
-
随着匹配需求的增加,正则表达式会变得越来越复杂,维护起来不直观。
字符串处理:
-
字符串处理方式直观、简单,代码逻辑容易理解和维护。尤其在时间解析这种任务中,字符串处理的思路清晰,后期维护和修改也比较方便。刚刚入门的人应该也能看懂代码逻辑。
-
但是在需要匹配多个复杂格式时,字符串处理的代码量会增加,可读性可能会下降。
使用字符串处理方式,但确保处理足够的边缘情况,要考虑的情况比较多,比如,可以在需要时手动修正不规范的输入(去掉多余的空格等),并结合基础的验证来确保数据有效性。
就文章开头的需求来说,这里的时间格式相对固定,而且不是用户输入的字符串,需要考虑的意外情况就少很多,这里字符串处理方式会更高效且易于维护。但是这里的数据量也不是很大,其实使用正则在效率上的影响也不大。
如果后续随着业务的增加,可以考虑字符串处理加上正则的方式,这样或许能更好的解决业务上的问题。没有一个完美的工具可以解决所有问题。