在 Javascript 中使用正则表达式容纳多个值

Posted

技术标签:

【中文标题】在 Javascript 中使用正则表达式容纳多个值【英文标题】:Accomodate multiple values using regex in Javascript 【发布时间】:2020-12-28 04:00:07 【问题描述】:

我有正则表达式字符串/^(?:\[)(.*)(?:\|)(.*)(?:\|)(.*)(?:\|)(.*)(?:\|)(.*)(?:\])$/,它捕获以下值[john|doe|doe@email.com|doe_avatar|manager]。 我也喜欢用[john|doe|doe@email.com|doe_avatar] 捕获值,两者都使用相同的正则表达式。我怎样才能在 Javascript 中做到这一点?

【问题讨论】:

【参考方案1】:

是的,这可以通过单个正则表达式实现,方法是将最后一段及其随附的管道 \| 包含在一个额外的、可选的、非捕获组 ((?:……)?) 中。

const regex =
    /^(?:\[)(.*?)(?:\|)(.*?)(?:\|)(.*?)(?:\|)(.*?)(?:(?:\|)(.*?))?(?:\])$/

const rows = [
    '[john|doe|doe@email.com|doe_avatar|manager]',
    '[jane|doe|jane@email.com|jane_avatar]',
]

const parse = str => 
    const m = str.match(regex)
    
    if (!m) return null
    
    const [fullMatch, forename, surname, email, avatar, role] = m
    
    return  fullMatch, forename, surname, email, avatar, role 


console.log(rows.map(parse))

正如@CertainPerformance 下面提到的,如果匹配不存在,则最终捕获组的结果将为undefined

【讨论】:

OP 说:我也喜欢使用相同的正则表达式捕获 [john|doe|doe@email.com|doe_avatar] 的值。 问题在于最后一个是否存在 - |doe_avatar,可能存在也可能不存在。要么不会捕获最后一个项目,要么会捕获它,但是在缺少最后一个项目的版本中,undefined 将被放入结果组中。无论哪种方式,都需要进行一些后期处理。 @CertainPerformance 哇,我真的看不懂。使用单个正则表达式仍然可以,但我完全回答了错误的问题。相应地编辑我的答案。 当最后一部分丢失时,它现在返回"role": undefined无论哪种方式,如果 OP 想要一组匹配的部分(并且想要避免在可能不平衡的括号内匹配元素),则需要进行一些后期处理。 OP 没有提到他们想要一组匹配的部分。 这对我有用。我只需要两个列表中的前四个值。谢谢@LionelRowe。我不能投票,因为我没有足够的积分。非常感谢【参考方案2】:

如果您希望每个部分都在一个单独的组中,那么在 JS 中的正则表达式模式的单次迭代中是不可能的(尽管在 .NET 和其他可以提取重复组匹配的风格中是可能的)。你能做到的最好的就是匹配[,最后匹配],然后再匹配|s:

const extract = (str) => 
  const insideBrackets = str.match(/\[([^\]]+)\]/)[1];
  const sections = insideBrackets.split('|');
  console.log(sections);
;
extract('[john|doe|doe@email.com|doe_avatar|manager]');
extract('[john|doe|doe@email.com|doe_avatar]');

【讨论】:

是的,在 JS 中是可以的。看我的回答

以上是关于在 Javascript 中使用正则表达式容纳多个值的主要内容,如果未能解决你的问题,请参考以下文章

javascript基础知识之正则表达式(regular expression)

用于在 javascript 中查找动态字符串中字符的第二次出现的正则表达式

JavaScript中的正则表达式

JavaScript正则表达

Javascript 正则表达式替换所有非货币字符

JavaScript正则表达式