从字符串中获取 x 天、小时和分钟并转换为 dd:hh:mm 的有效方法
Efficient way to get x Days, hours, and minutes from string and convert to dd:hh:mm
我有一个可以 return 为 1 days 15 hours 08 minutes
的字符串,我想将其转换为 dd:hh:mm
.
的格式
该字符串也不能包含任何天数,看起来像 15 hours 08 mintues
。
我的想法是用正则表达式抓取所有数字组并检查 returned 的计数。如果有 3 个,我知道我可以假设会有 dd:hh:mm
。如果有两个,我会知道我有 hh:mm
等...
另一种选择是将字符串分解成可能的 3 个字符串..."1 days", "15 hours", "08 minutes"
然后从中获取数字以构建我正在寻找的格式...
使用 Javascript 执行此操作的最有效方法是什么?
match() 数字组,returns 一个数组,map() 中的 padStart() 在需要时添加前导零,并用冒号分隔符加入 ()。
不确定如何处理 3 位数的天数,或者是否有可能。
以下假定始终包括小时和分钟,天数可选
const input = ['1 days 15 hours 08 minutes', '15 hours 08 mintues', '22 days 1 hours 0 minutes'];
const timeFromString = (str) => {
const digits = str.match(/\d+/g);
if (digits.length === 2) {
digits.unshift('00');
}
return digits.map(s => s.padStart(2, '0')).join(':')
}
input.forEach(s=> console.log(timeFromString(s)))
.as-console-wrapper {
max-height: 100%!important;
top: 0;
}
效率最高?那将是在将这些数字连接成字符串之前获取这些数字。然而,我离题了:
function dhm(string){
const s = string.match(/[0-9]+/g);
let d = 0, h = 0, m = 0;
switch(s.length){
case 3:
d = +s[0]; h = +s[1]; m = +s[2];
break;
case 2:
d = +s[0]; h = +s[1];
break;
case 1:
d = +s[0];
break;
}
if(d < 10)d = '0'+d;
if(h < 10)h = '0'+h;
if(m < 10)m = '0'+m;
return d+':'+h+':'+m;
}
const result = dhm('1 days 15 hours 08 minutes');
console.log(result);
请注意,您的格式可能会使客户感到困惑,因为它看起来确实像 hh:mm:ss
。
类似的东西?
const dhm = (function()
{
const keys = [ 'days','hours','minutes' ]
return (val) =>
{
let res = ['00','00','00' ]
, num = ''
val.split(' ').forEach((inVal,i)=>
{
if (i&1) // i is odd
{
let p = keys.indexOf(inVal)
if (p > -1) res[p] = num.padStart(2, '0')
}
else num = inVal // i is even
})
return res.join(':')
}
})();
[ '1 days 15 hours 08 minutes'
, '15 hours 08 minutes'
, '3 days 6 minutes' ].forEach(el => console.log(el,'->',dhm(el)))
.as-console-wrapper {max-height: 100%!important;top:0;}
一种基于正则表达式的方法,其特点是 named capture groups 如下所示 ...
/(?:\s*(?<days>\d+)\s*days*)?(?:\s*(?<hours>\d+)\s*hours*)?(?:\s*(?<minutes>\d+)\s*minutes*)?/
...结合destructuring assignment和方便的格式辅助功能...
function formatDDHHMM(copy) {
function doubleDigit(str) {
return ((str.length === 1) && `0${ str }`) || str;
}
const {
days,
hours,
minutes
} = copy.match(
// see ... [https://regex101.com/r/HDrbb9/1]
/(?:\s*(?<days>\d+)\s*days*)?(?:\s*(?<hours>\d+)\s*hours*)?(?:\s*(?<minutes>\d+)\s*minutes*)?/
).groups;
return [
doubleDigit(days || '00'),
doubleDigit(hours || '00'),
doubleDigit(minutes || '00'),
].join(':');
}
const sampleList = [
'1 day 15hours 08 minutes',
'1days 15 hour',
'15 hours 08minute',
'1 days 08 minutes',
'08minutes',
'15 hours',
'1 day',
];
console.log(
'sampleList.map(formatDDHHMM) ...',
sampleList.map(formatDDHHMM)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
我有一个可以 return 为 1 days 15 hours 08 minutes
的字符串,我想将其转换为 dd:hh:mm
.
该字符串也不能包含任何天数,看起来像 15 hours 08 mintues
。
我的想法是用正则表达式抓取所有数字组并检查 returned 的计数。如果有 3 个,我知道我可以假设会有 dd:hh:mm
。如果有两个,我会知道我有 hh:mm
等...
另一种选择是将字符串分解成可能的 3 个字符串..."1 days", "15 hours", "08 minutes"
然后从中获取数字以构建我正在寻找的格式...
使用 Javascript 执行此操作的最有效方法是什么?
match() 数字组,returns 一个数组,map() 中的 padStart() 在需要时添加前导零,并用冒号分隔符加入 ()。
不确定如何处理 3 位数的天数,或者是否有可能。
以下假定始终包括小时和分钟,天数可选
const input = ['1 days 15 hours 08 minutes', '15 hours 08 mintues', '22 days 1 hours 0 minutes'];
const timeFromString = (str) => {
const digits = str.match(/\d+/g);
if (digits.length === 2) {
digits.unshift('00');
}
return digits.map(s => s.padStart(2, '0')).join(':')
}
input.forEach(s=> console.log(timeFromString(s)))
.as-console-wrapper {
max-height: 100%!important;
top: 0;
}
效率最高?那将是在将这些数字连接成字符串之前获取这些数字。然而,我离题了:
function dhm(string){
const s = string.match(/[0-9]+/g);
let d = 0, h = 0, m = 0;
switch(s.length){
case 3:
d = +s[0]; h = +s[1]; m = +s[2];
break;
case 2:
d = +s[0]; h = +s[1];
break;
case 1:
d = +s[0];
break;
}
if(d < 10)d = '0'+d;
if(h < 10)h = '0'+h;
if(m < 10)m = '0'+m;
return d+':'+h+':'+m;
}
const result = dhm('1 days 15 hours 08 minutes');
console.log(result);
请注意,您的格式可能会使客户感到困惑,因为它看起来确实像 hh:mm:ss
。
类似的东西?
const dhm = (function()
{
const keys = [ 'days','hours','minutes' ]
return (val) =>
{
let res = ['00','00','00' ]
, num = ''
val.split(' ').forEach((inVal,i)=>
{
if (i&1) // i is odd
{
let p = keys.indexOf(inVal)
if (p > -1) res[p] = num.padStart(2, '0')
}
else num = inVal // i is even
})
return res.join(':')
}
})();
[ '1 days 15 hours 08 minutes'
, '15 hours 08 minutes'
, '3 days 6 minutes' ].forEach(el => console.log(el,'->',dhm(el)))
.as-console-wrapper {max-height: 100%!important;top:0;}
一种基于正则表达式的方法,其特点是 named capture groups 如下所示 ...
/(?:\s*(?<days>\d+)\s*days*)?(?:\s*(?<hours>\d+)\s*hours*)?(?:\s*(?<minutes>\d+)\s*minutes*)?/
...结合destructuring assignment和方便的格式辅助功能...
function formatDDHHMM(copy) {
function doubleDigit(str) {
return ((str.length === 1) && `0${ str }`) || str;
}
const {
days,
hours,
minutes
} = copy.match(
// see ... [https://regex101.com/r/HDrbb9/1]
/(?:\s*(?<days>\d+)\s*days*)?(?:\s*(?<hours>\d+)\s*hours*)?(?:\s*(?<minutes>\d+)\s*minutes*)?/
).groups;
return [
doubleDigit(days || '00'),
doubleDigit(hours || '00'),
doubleDigit(minutes || '00'),
].join(':');
}
const sampleList = [
'1 day 15hours 08 minutes',
'1days 15 hour',
'15 hours 08minute',
'1 days 08 minutes',
'08minutes',
'15 hours',
'1 day',
];
console.log(
'sampleList.map(formatDDHHMM) ...',
sampleList.map(formatDDHHMM)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }