如何在定义的组中添加 special/non-word 个字符?

How to add special/non-word character in defined groups?

我有一个正则表达式,它给我单独的字符串组。

旧正则表达式

const regex = /^(.*?)((?:\d{1,3}(?:,\d{1,3})*|\d+)(?:\.\d{1,5})?)(\D.*)?$/g;

我写的新正则表达式,但不确定它是否正确

const regex = /^(.*?)((?:([^\w\*])|(\d{1,3})(?:,\d{1,3})*|\d+)(?:\.\d{1,5})?)(\D.*)?$/g

这是我的正则表达式解释,主要是我以前在 Group 2 中有数字,但现在我的输入范围在增加,我希望 - (非单词字符)也能被识别它。

但是IDK如果有可能在Group 2中添加-

PS:除了 -numbers 之外不会有任何不同的字符 输入如下

const inputs= ["0","$(200)%","100%","$-","$(52,000.5617)%",",000","45,444%"];
const regex = /^(.*?)((?:([^\w\*])|(\d{1,3})(?:,\d{1,3})*|\d+)(?:\.\d{1,5})?)(\D.*)?$/g;
const text = inputs.match(regex);
let [_, preText = "", number = "", postText = ""] = text;

  1. ^ - start of string (.*?) - Group 1 (preText): any zero or more
    chars other than line break chars, as few as possible

    
  2. ((?:\d{1,3}(?:,\d{1,3})*|\d+)(?:\.\d{1,5})?) - Group 2 (number): one
    to three digits followed with zero or more occurrences of a comma
    and one to three digits, or just one or more digits, and then an
    optional sequence of a . and one to five digits
    
  3. (\D.*)? - Group 3 (postText), optional: a non-digit char and then
    any zero or more chars other than line break chars, as many as
    possible $ - end of string.

输出:

  1. 这是我从旧正则表达式得到的输出
[_ = "$(52,000.5617)%", preText = "$", number = "52,000.5617", postText = ")%"]
  1. 这是我的预期输出
[_ = "$-", preText = "$", number = "-", postText = ""]
  1. 没有preText
[_ = "45,444%", preText = "", number = "45,444", postText = "%"]

您可以使模式更具体一些,然后允许/禁止您想要捕获的内容。

您可以使用 3 个没有重叠匹配的可选捕获组,并使用不匹配空字符串的否定先行。

^(?!$)($?[^\d\n-]*)(-?(?:\d{1,3}(?:,\d{3})*(?:\.\d{1,5})?|\d+)?)([^\d\n]*)$

说明

  • ^ 字符串开头
  • (?!$)不直接断言字符串结束
  • ($?) 捕获 组 1,匹配可选 $
  • [^\d\n-]* 可选择匹配除数字、换行符或 -
  • 以外的字符
  • ( 捕获 第 2 组
    • -? 匹配可选 -
    • (?:非捕获组
      • \d{1,3}匹配1-3位数字
      • (?:,\d{3})*重复1+次,和3个数字
      • (?:\.\d{1,5})?匹配可选.和1-5位数字
      • |
      • \d+ 匹配 1+ 个数字
    • )?关闭非捕获组并使其可选
  • ) 关闭组 2
  • ([^\d\n]*) 捕获 组 3,匹配数字或换行符以外的字符

Regex demo

const inputs = ["0", "$(200)%", "100%", "$-", "$(52,000.5617)%", ",000", "45,444%"];
const regex = /^(?!$)($?[^\d\n-]*)(-?(?:\d{1,3}(?:,\d{3})*(?:\.\d{1,5})?|\d+)?)([^\d\n]*)$/;
inputs.forEach(s => {
  const m = s.match(regex);
  if (m) {
    let [_, preText = "", number = "", postText = ""] = m;
    console.log("input --> " + s);
    console.log("preText --> " + preText);
    console.log("number --> " + number);
    console.log("postText --> " + postText);
    console.log("------------------------------------");
  }
});