[英]how to extract specific character from a string using regex
我将有以下输入,我计划从中提取单位
(预期 output 例如: g
、 l
、 kg
、 ml
、 l
)和数量(如果存在)(最后输入为20
)
0,5g
500l
1000kg
20,5ml
20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand
如果是简单的情况,我正在执行以下操作
输入: 500g
console.log("500g".replace(/ *\([^)]*\) */g, "") // remove brackets
.replace(/[0-9]/g, "") // remove number eg. 500
.replace(/\s/g, ""))
output: g
(工作)
输入: 0,5g
console.log("0,5g".replace(/ *\([^)]*\) */g, "") // remove brackets
.replace(/[0-9]/g, "") // remove number eg. 500g
.replace(/\s/g, ""))
output: ,g
(休息)
输入: 20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand
20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand
console.log("20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand".replace(/ *\([^)]*\) */g, "") // remove brackets
.replace(/[0-9]/g, "") // remove number eg. 500g
.replace(/\s/g, ""))
output: x,lzzgl.,€Pfand
(休息)
您可能希望使用match
而不是使用replace
,这将返回匹配 object。
正则表达式模式:
对于匹配值和单位:
([\d,\.]+)\s*(g|kg|l|ml)
最后一组可以添加更多单位。
例子:
"20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand".match(/([\d,\.]+)\s*(g|kg|l|ml)/)
returns
(3) ...:
0: "0,50l" // full match
1: "0,50" // value
2: "l" // unit
...
仅匹配单位(虽然这有点不必要,但前面的正则表达式同时匹配第 1 组中的值,第 2 组中的单位):
(?<=[\d,\.]+)\s*(g|kg|l|ml)
对于匹配数量:
([\d,\.]+)(?:x|\*)
例子:
"20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand".match(/([\d,\.]+)(?:x|\*)/)
returns
(2) ...:
0: "20x" // full match
1: "20" // quantity
...
编辑:进一步详细说明我的评论
var units = ["g", "kg", "l", "ml"];
var re = new RegExp(`([\\d,\\.]+)\\s*(${units.join("|")})`);
然后使用 re 进行匹配:
"20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand".match(re)
工作方式相同,但更易于维护。
您可以使用 2 个捕获组来提取单位和可选的 20
(?:(\d+)x\d+(?:,\d+)?)?\d+(k?g|g|m?l)
捕获组 1 可选地匹配数量,如 20(如果存在),捕获组 2 匹配单位。
解释
(?:
非捕获组,使整个部分可选
(\d+)x
捕获组 1 ,匹配 1+ 个数字后跟x
\d+(?:,\d+)?
匹配 1+ 位和可选的小数部分)?
关闭组并使其可选\d+
匹配 1+ 个数字(k?g|g|m?l)
捕获组 2 ,匹配任何列出的备选方案 const regex = /(?:(\d+)x\d+(?:,\d+)?)?\d+(k?g|g|m?l)/g; [ "0,5g", "500l", "1000kg", "20,5ml", "20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand", ].forEach(s => console.log(Array.from(s.matchAll(regex), m => [m[1]? m[1]: "", m[2]])));
这样的事情可能会做,提取单位、数量和剂量:
const convert = (input) => { const match = /(?:(\d+)x)?\s*([\d\,.]+)([az]+)/i.exec (input) return match? { quantity: Number(match [2].replace(/\,/g, '.')), unit: match [3], ...(match [1]? {doses: Number(match [1].replace(/,/g, '.'))}: {}) }: {} } const inputs = ['500g', '0,5g', '500l', '1000kg', '20,5ml', '20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand'] inputs.forEach ( input => console.log (`"${input}" --> ${JSON.stringify(convert(input))}`) )
.as-console-wrapper {max-height: 100%;important: top: 0}
请注意,数字处理是幼稚的。 它只查找数字、逗号和句点的任意组合,这意味着它也可能接受'12,345,6.7.8'
。 如果您的数据有问题,我相信我们可以解决这个问题。
我们的正则表达式如下所示:
/(?:(\d+)x)?\s*([\d\,.]+)([a-z]+)/i
// \_______/ \_/ \______/ \_____/\_/
// | | | | +--- Case insensitive, accepts 'KG' as well as 'kg'
// | | | +-------- Capturing group for units, composed of letters.
// | | +----------------- Capturing group for quantity, composed of
// | | digits, commas, and periods.
// | +----------------------- Optional space after dosage
// +------------------------------ Optional non-capturing group with
// - a capturing group of digits
// - the literal character `x1```
注意,较早的版本没有处理剂量,也没有将数量和剂量转换为数字,更简单:
const convert = (input) => {
const match = /([\d\,.]+)([a-z]+)(?![a-z0-9])/i .exec (input)
return match
? {qty: match [1], unit: match [2]}
: {}
}
当然,如果我们只是想要单位,我们可以这样:
const convert2 = (input) => /(?:(?:\d+)x)?\s*(?:[\d\,.]+)([az]+)/i.exec (input) [1] const inputs = ['500g', '0,5g', '500l', '1000kg', '20,5ml', '20x0,50l (1 l = 1,70 €) zzgl. 3,10€ Pfand'] inputs.forEach ( input => console.log (`"${input}" --> ${JSON.stringify(convert2(input))}`) )
.as-console-wrapper {max-height: 100%;important: top: 0}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.