我试图解析以下类型的字符串:

[key:"val" key2:"val2"]

其中有任意键:“val”对在里面。我想获取键名和值。 对于那些好奇的人,我试图解析任务战士的数据库格式。

这是我的测试字符串:

[description:"aoeu" uuid:"123sth"]

这意味着除了空格之外,任何东西都可以放在键或值中,冒号周围没有空格,值总是在双引号中。

在node中,这是我的输出:

[deuteronomy][gatlin][~]$ node
> var re = /^\[(?:(.+?):"(.+?)"\s*)+\]$/g
> re.exec('[description:"aoeu" uuid:"123sth"]');
[ '[description:"aoeu" uuid:"123sth"]',
  'uuid',
  '123sth',
  index: 0,
  input: '[description:"aoeu" uuid:"123sth"]' ]

但是描述:“aoeu”也符合这个模式。我怎么能得到所有的比赛回来?


当前回答

以下是我的回答:

var str = '[me nombre es] : My name is. [Yo puedo] is the right word'; 

var reg = /\[(.*?)\]/g;

var a = str.match(reg);

a = a.toString().replace(/[\[\]]/g, "").split(','));

其他回答

我的猜测是,如果有边界情况,比如额外的或缺失的空格,这种边界更少的表达式也可能是一种选择:

^\s*\[\s*([^\s\r\n:]+)\s*:\s*"([^"]*)"\s*([^\s\r\n:]+)\s*:\s*"([^"]*)"\s*\]\s*$

如果你想探索/简化/修改这个表达式,它已经被 在右上方的面板上有解释 regex101.com。如果你愿意,你可以 还能在这看吗 链接,如何匹配 对照一些样本输入。


Test

const regex = /^\s*\[\s*([^\s\r\n:]+)\s*:\s*"([^"]*)"\s*([^\s\r\n:]+)\s*:\s*"([^"]*)"\s*\]\s*$/gm; const str = `[description:"aoeu" uuid:"123sth"] [description : "aoeu" uuid: "123sth"] [ description : "aoeu" uuid: "123sth" ] [ description : "aoeu" uuid : "123sth" ] [ description : "aoeu"uuid : "123sth" ] `; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } // The result can be accessed through the `m`-variable. m.forEach((match, groupIndex) => { console.log(`Found match, group ${groupIndex}: ${match}`); }); }

RegEx电路

jex。Im可视化正则表达式:

基于Agus的函数,但我更喜欢返回匹配值:

var bob = "> bob <";
function matchAll(str, regex) {
    var res = [];
    var m;
    if (regex.global) {
        while (m = regex.exec(str)) {
            res.push(m[1]);
        }
    } else {
        if (m = regex.exec(str)) {
            res.push(m[1]);
        }
    }
    return res;
}
var Amatch = matchAll(bob, /(&.*?;)/g);
console.log(Amatch);  // yeilds: [>, <]

Str.match (pattern),如果pattern具有全局标志g,将以数组形式返回所有匹配项。

例如:

const str = '除了@Emran, @Raju和@Noman,我们都在那里'; console.log ( str.match (/ @ \ w * / g) ); // Will log ["@Emran", "@Raju", "@Noman"]

str.match(/regex/g)

以数组形式返回所有匹配项。

如果出于某种神秘的原因,您需要exec附带的额外信息,作为前面答案的替代方案,您可以使用递归函数来代替循环,如下所示(这看起来也很酷:)。

function findMatches(regex, str, matches = []) {
   const res = regex.exec(str)
   res && matches.push(res) && findMatches(regex, str, matches)
   return matches
}

// Usage
const matches = findMatches(/regex/g, str)

正如前面的评论中所述,在regex定义的末尾加上g,以便在每次执行时将指针向前移动,这很重要。

如果你能够使用matchAll,这里有一个技巧:

数组中。From有一个“选择器”参数,这样你就不会得到一个尴尬的“匹配”结果数组,你可以把它投射到你真正需要的东西上:

Array.from(str.matchAll(regexp), m => m[0]);

如果你已经命名了组。(/(?<firstname>[a-z][a-z] +)/g)你可以这样做:

Array.from(str.matchAll(regexp), m => m.groups.firstName);