繁体   English   中英

如何使用正则表达式从字符串中提取特定字符

[英]how to extract specific character from a string using regex

我将有以下输入,我计划从中提取单位
(预期 output 例如: glkgmll )和数量(如果存在)(最后输入为20

  1. 0,5g
  2. 500l
  3. 1000kg
  4. 20,5ml
  5. 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。

Mozilla 文章


正则表达式模式:

对于匹配值和单位:

([\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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM