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

[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”也符合这个模式。我怎么能得到所有的比赛回来?


当前回答

如果你有ES9

(意思是如果你的系统:Chrome, Node.js, Firefox等支持Ecmascript 2019或更高版本) 使用新的yourString。matchAll(/your-regex/g)。

如果你没有ES9

如果您使用的是较旧的系统,这里有一个简单的复制和粘贴函数

function findAll(regexPattern, sourceString) {
    let output = []
    let match
    // auto-add global flag while keeping others as-is
    let regexPatternWithGlobal = RegExp(regexPattern,[...new Set("g"+regexPattern.flags)].join(""))
    while (match = regexPatternWithGlobal.exec(sourceString)) {
        // get rid of the string copy
        delete match.input
        // store the match data
        output.push(match)
    } 
    return output
}

使用示例:

console.log(   findAll(/blah/g,'blah1 blah2')   ) 

输出:

[ [ 'blah', index: 0 ], [ 'blah', index: 6 ] ]

其他回答

这里有一个没有while循环的一行解决方案。

结果列表中保留该顺序。

潜在的缺点是

它为每个匹配复制正则表达式。 结果与预期的解形式不同。你需要再处理一次。

let re = /\s*([^[:]+):\"([^"]+)"/g
let str = '[description:"aoeu" uuid:"123sth"]'

(str.match(re) || []).map(e => RegExp(re.source, re.flags).exec(e))

[ [ 'description:"aoeu"',
    'description',
    'aoeu',
    index: 0,
    input: 'description:"aoeu"',
    groups: undefined ],
  [ ' uuid:"123sth"',
    'uuid',
    '123sth',
    index: 0,
    input: ' uuid:"123sth"',
    groups: undefined ] ]

如果你能够使用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);

如果你有ES9

(意思是如果你的系统:Chrome, Node.js, Firefox等支持Ecmascript 2019或更高版本) 使用新的yourString。matchAll(/your-regex/g)。

如果你没有ES9

如果您使用的是较旧的系统,这里有一个简单的复制和粘贴函数

function findAll(regexPattern, sourceString) {
    let output = []
    let match
    // auto-add global flag while keeping others as-is
    let regexPatternWithGlobal = RegExp(regexPattern,[...new Set("g"+regexPattern.flags)].join(""))
    while (match = regexPatternWithGlobal.exec(sourceString)) {
        // get rid of the string copy
        delete match.input
        // store the match data
        output.push(match)
    } 
    return output
}

使用示例:

console.log(   findAll(/blah/g,'blah1 blah2')   ) 

输出:

[ [ 'blah', index: 0 ], [ 'blah', index: 6 ] ]

继续在循环中调用re.exec(s)以获取所有匹配项:

var re = /\s*([^[:]+):\"([^"]+)"/g;
var s = '[description:"aoeu" uuid:"123sth"]';
var m;

do {
    m = re.exec(s);
    if (m) {
        console.log(m[1], m[2]);
    }
} while (m);

试试这个JSFiddle: https://jsfiddle.net/7yS2V/

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

例如:

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