【问题标题】:Extract parts from bracketed string从括号中的字符串中提取部分
【发布时间】:2020-03-20 19:41:30
【问题描述】:

有一个字符串的某些部分用括号标记:

abc(de)f(uv)xyz

如何将其拆分为以下部分:

abc | false
de | true
f | false
uv | true
xyz | false

其中 true 代表括号内的部分,false 代表未加括号的部分。

注意括号仅用于标记目的。嵌套的、不成对的括号和其他复杂的场景是不可能的。

【问题讨论】:

  • 预期输出是什么 - 只是零件还是 true/false
  • 另外,字符串的语法是否保证一致和正确,这意味着打开和关闭括号总是匹配abc(de)f,或者也可以有随机括号,如abcd)e(f)
  • @AndreasPizsa 部分和布尔值。输出应该允许它迭代并恢复源字符串。
  • @AndreasPizsa 括号序列保证有效且不包含嵌套序列。

标签: regex string brackets


【解决方案1】:

正则表达式

鉴于括号序列保证有效且不包含嵌套序列,我们可以保持正则表达式非常简单:

\(?([^()]+)\)?

  1. \(? - 可选择接受左括号
  2. ([^()]+)- 捕获任何不是左括号或右括号的内容
  3. \)? - 可选择接受右括号

代码

执行正则表达式

一旦我们执行正则表达式 (execAll(pattern, text)),我们就会得到

const matches = execAll(pattern, text)

[
  ['abc', 'abc'],
  ['(de)', 'de'],
  ['f'   , 'f' ]
  ['(uv)', 'uv'],
  ['xyz', 'xyz']
]

带括号的 vs 不带括号的

每个条目的索引0 是匹配的文本,索引1 是捕获的组。

查看索引0 的第一个字符告诉我们它是否是一个组:

matches[0][0] === '(' // false
matches[1][0] === '(' // true

按正确的顺序排列

我们首先要文本,然后是布尔值:

matches.map(([bracket, group]) => [group, bracket[0]==='('])

[
  ['abc', false],
  ['de' , true ],
  ['f'  , false]
  ['uv' , true ],
  ['xyz', false]
]

完成!

解决方案

const execAll = (pattern, str) => {
    const result=[]
    let match
    while((match = pattern.exec(str))) {
        result.push(match)
    }
    return result
}

const extractGroups = text => {
  const pattern = /\(?([^()]+)\)?/g
  const matches = execAll(pattern, text)
  return matches
    .map(([bracket, group]) => [group, bracket[0]==='('])
}
  
console.log(extractGroups('abc(de)f(uv)xyz'))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多