如何在没有正则表达式的情况下安全地区分 ISO 8601 字符串和在 queryParams 中存储为字符串的数字
how to safely distinguish ISO 8601 string and number stored as string in queryParams without regex
例如,我有一个日期和金额 属性 存储在 url als 查询参数中
...?date=2019-06-12T06:20:39.465Z&amount=20000
我希望能够解析所有查询参数并使用 javascript 将它们分配给正确的类型。
目前我正在使用
paramMap.keys.forEach(key => {
let value: any = paramMap.get(key);
if (isFinite(Date.parse(value))) {
// keep as string
} else if (isFinite(parseInt(value, 10))) {
value = isInteger(value) ? parseInt(value, 10) : parseFloat(value);
} else if (value === 'true' || value === 'false') {
value = value === 'true';
}
obj[key] = value;
});
return obj;
在这种情况下,amount=20000 将被 Date.parse 识别。
还有
2019-06-12T06:20:39.465Z 将使用 parseInt 解析为 2019...
isFinie、parseInt 和 isInteger 是从 lodash 导入的。
如果可能我不想使用正则表达式。
编辑:请假设我不知道密钥的名称。因此该脚本应该适用于所有属性。
ISO 可能会忽略秒、时区或毫秒,但如果您忽略这些并检查其他所有内容,您就可以可靠地检查不同的 ISO 格式。
console.log(isISO('2019-06-12T06:20:39.234Z'))
console.log(isISO('2019-06-12T06:20:39'))
console.log(isISO('2019-06-12T06:20'))
console.log(isISO("2019-1-1"))
console.log(isISO('2019-06-12T06:20:39+05'))
console.log(isISO('ketchup'))
function isISO(str) {
try {
str = str.split('+')[0];
var iso = new Date(str).toISOString();
var [date, time] = iso.split('T');
var [y, m, d] = date.split('-');
return iso.indexOf(`${y}-${m}-${d}`) === 0;
} catch (e) {
return false;
}
}
使用 +
operator, the Number function, or lodash's _.toNumber()
将 return NaN
用于带混合数字的字符串:
console.log(+'2019-06-12T06:20:39.465Z')
console.log(+'20000')
所以逻辑是:
const parseParam = value => {
let v = +value
if (!isNaN(v)) return v
v = Date.parse(value)
if (!isNaN(v)) return v
if (value === 'true' || value === 'false') return value === 'true'
return value
}
console.log(parseParam('2019-06-12T06:20:39.465Z'))
console.log(parseParam('20000'))
console.log(parseParam('false'))
console.log(parseParam('cats'))
例如,我有一个日期和金额 属性 存储在 url als 查询参数中
...?date=2019-06-12T06:20:39.465Z&amount=20000
我希望能够解析所有查询参数并使用 javascript 将它们分配给正确的类型。
目前我正在使用
paramMap.keys.forEach(key => {
let value: any = paramMap.get(key);
if (isFinite(Date.parse(value))) {
// keep as string
} else if (isFinite(parseInt(value, 10))) {
value = isInteger(value) ? parseInt(value, 10) : parseFloat(value);
} else if (value === 'true' || value === 'false') {
value = value === 'true';
}
obj[key] = value;
});
return obj;
在这种情况下,amount=20000 将被 Date.parse 识别。
还有
2019-06-12T06:20:39.465Z 将使用 parseInt 解析为 2019...
isFinie、parseInt 和 isInteger 是从 lodash 导入的。
如果可能我不想使用正则表达式。
编辑:请假设我不知道密钥的名称。因此该脚本应该适用于所有属性。
ISO 可能会忽略秒、时区或毫秒,但如果您忽略这些并检查其他所有内容,您就可以可靠地检查不同的 ISO 格式。
console.log(isISO('2019-06-12T06:20:39.234Z'))
console.log(isISO('2019-06-12T06:20:39'))
console.log(isISO('2019-06-12T06:20'))
console.log(isISO("2019-1-1"))
console.log(isISO('2019-06-12T06:20:39+05'))
console.log(isISO('ketchup'))
function isISO(str) {
try {
str = str.split('+')[0];
var iso = new Date(str).toISOString();
var [date, time] = iso.split('T');
var [y, m, d] = date.split('-');
return iso.indexOf(`${y}-${m}-${d}`) === 0;
} catch (e) {
return false;
}
}
使用 +
operator, the Number function, or lodash's _.toNumber()
将 return NaN
用于带混合数字的字符串:
console.log(+'2019-06-12T06:20:39.465Z')
console.log(+'20000')
所以逻辑是:
const parseParam = value => {
let v = +value
if (!isNaN(v)) return v
v = Date.parse(value)
if (!isNaN(v)) return v
if (value === 'true' || value === 'false') return value === 'true'
return value
}
console.log(parseParam('2019-06-12T06:20:39.465Z'))
console.log(parseParam('20000'))
console.log(parseParam('false'))
console.log(parseParam('cats'))