尝试使用RegEx(在JS中)获得由两个终止符之间的特殊字符分隔的所有值

Trying to use RegEx (in JS) to get all values delimited by a special character, between two terminators

本文关键字:之间 两个 终止 特殊字符 分隔 RegEx JS      更新时间:2023-09-26

我试图使用regex从一个更大的字符串中找到一个自定义格式化字符串的多个实例(为了这篇文章的缘故,我们称之为)。宏基本上是一个字符串,以{开头,以}结尾,然后有小写字母数值连字符和(可能)句号,所有这些都由冒号(:)

分隔。

宏的第一个片段 (有时是唯一的部分)可以是数值小写字母,长度在1到5个字符之间。 :

  1. {foo}
  2. {barbaz}
  3. {1}
  4. {1234}

但是,为了使它更复杂,这些可能有"修饰符",它们都用冒号分隔。这些修饰符可以是:

  • 大写字符一个或两个字符长(例如:aab)
  • 数值(如: 12 , , 1123123 )
  • 数值中间或前面有连字符的数值(例如:1-2-12)

宏示例

这里有一个可能使用的宏的简短列表,以及我正在寻找的Regex数组结果

    宏观:
  1. {foo} 正则表达式匹配: ["foo"]
  2. 宏: {foo:ab:cd:e:f:g} Regex匹配: ["foo","ab","cd","e", "f","g"]
  3. 宏: {bar:1-3} Regex匹配: ["bar","1-3"]
  4. 宏: {baz:r:uc} Regex匹配: ["baz","r","uc"]
  5. 宏: {quux:1:2:uc} Regex匹配: ["quux","1","2","uc"]
<

例子段落/h3>

我需要这个查询能够找到多个宏在一个较大的段落,例如:

My name is {namel:uf}, {namef:uf}, I go to {highschool:uw}. My computer username is {namef:1:l}{namel:l}
Test string: {foo}
Test string: ucfirst: {foo:uf}
Test string reversed/uppercase: {foo:u:r}
First 3 chars of test string: {foo:3}
Last 2 chars of test string: {foo:-2}

我正在寻找一个正则表达式模式,将返回:

[
    ['namel','uf'],
    ['namef','uf'],
    ['highschool','uw'],
    ['namef','l',0],
    ['namel','l'],
    ['foo'],
    ['foo','uf'],
    ['foo','u','r'],
    ['foo',3],
    ['foo','-2']
]

目前进展

我已经为此工作了一段时间,我很确定我有点接近....我现在的模式是:

/'{(([a-z]{1,10}|'d+)+)(':([a-z]{1,2}|'-?'d+|'d+'-'d+)*)*'}/gm

这里是regex101.com实例。

正如您所看到的,它与宏匹配得很好,但是我遇到了两个问题:

问题
  1. 它将匹配分隔修饰符
  2. :字符
  3. 似乎不匹配所有修饰符。看一下Regex101测试字符串中的#2,即{foo:ab:cd:e:f:g}。我希望结果是:["foo","ab","cd","e","f","g"],但相反,它匹配["foo","foo",":g","g"]

任何帮助将不胜感激!谢谢你!

- j

更新

我想我已经修复了上面列出的问题#1,它返回了一些:分隔符。我所做的就是将?:添加到通过查找冒号开始模式的组中,使其成为非捕获组。(也做了另一个改变,现在数值被处理,但这是不相关的)

这是新的模式

/'{(([a-z]{1,10}|'d+)+)(?:':([a-z]{1,2}|'d*'-?'d+)*)*'}/gm

下面是更新后的regex101.com示例。您仍然可以看到问题#2仍然存在,这意味着它不匹配每个宏修饰符,它看起来像是只匹配第一个和最后一个。

谢谢!

您可以使用.match()RegExp /'{'w+'}|'{'w+:('w+|'d+)'}|'{'w+:('w+|'d+):('w+|'d+)'}/g, .map(), .replace()RegExp /'{|'}/g, .split()RegExp /:/

var str = `My name is {namel:uf}, {namef:uf}, I go to {highschool:uw}. My computer username is {namef:1:l}{namel:l}
Test string: {foo}
Test string: ucfirst: {foo:uf}
Test string reversed/uppercase: {foo:u:r}
First 3 chars of test string: {foo:3}
Last 2 chars of test string: {foo:-2}`;
var res = str.match(/'{'w+'}|'{'w+:('w+|'d+)'}|'{'w+:('w+|'d+):('w+|'d+)'}/g);
res = res.map(s => s.replace(/'{|'}/g, "").split(/:/));
console.log(res);