我有一个字符串,希望从中删除具有以下属性的所有子字符串:

1. They start with an arbitrary (non-zero) number of open parenthesis
2. Then follows an arbitrary set of word characters (`\w`)
3. Then follows the same number of closing parenthesis as there have been open parenthesis.

纯正则表达式不能匹配开括号和闭括号.我第一次try wsa找到一种动态使用反向引用的方法.我知道这不是有效的Ruby,但给你一个 idea :

sttrep = str.gsub(/([(]+) \w+ [)]#{\1.size}/x, '')

当然是\1.大小无效;但是,有没有一种方法可以使用插值,在这种方法中,我可以基于反向参考来判断某些东西?

另一种可能是在循环中重复使用gsub,并一次删除一级括号:

tmpstr = str
loop do
  strrep = tmpstr.gsub(/[(] ([(]\w+[)]) [)]/x, "(\\1)")
  if tmpstr == strrep
    # We only have one level of parenthesis to consider
    sttrep = str.gsub(/[(]\w+[)]/x, '')
    break
  else
    tmpstr = strrep
  end
end
# strrep is now the resulting string
    

然而,这似乎是一个过于复杂的解决方案.有什么 idea 吗(当然,除了编写owen字符串解析器,它循环遍历每个字符并计算括号)?

UPDATE:

示例1:

str = "ab((((cd))))ef((gh))ij(kl)mn"

strrep应包含abefijmn.

示例2:

str = "((((abc));def;((ghi)))"

strrep应包含(;def;).

推荐答案

通常,要匹配所描述的字符串,需要使用regex子 routine :

(\((?:\w+|\g<1>)?\))

请参见regex demo.

Details:

  • (\((?:\w+|\g<1>)?\)) - Group 1 (capturing is necessary for recursion purposes):
    • \(-(字符
    • (?:\w+|\g<1>)?-可选出现一个或多个字字符或递归的组1模式
    • \)-)个字符.

为了提高效率,请考虑使用原子组而不是非捕获组:

(\((?>\w+|\g<1>)?\))
    ^^

参见Ruby demo:

puts [
    'ab((((cd))))ef((gh))ij(kl)mn',
    '((((abc));def;((ghi)))',
    '(((foo)) , bar)'
].map {|x| x.gsub(/(\((?:\w+|\g<1>)?\))/, '')}

输出:

abefijmn
((;def;)
( , bar)

Ruby相关问答推荐

如何在 Ruby 中验证来自多项 Select 提示的命令行输入?

如何使 Sinatra 通过 HTTPS/SSL 工作?

Ruby |= 赋值运算符

从 Time 对象获取下/上个月

如何正确截断表格?

Rails 类 << self

如何将参数传递给 array.map 快捷方式?

从Electron邮件中删除签名和回复

Puppet/Facter无法检索事实 fqdn:如何修复或规避?

在 ruby​​ 异常中捕获行号

动态设置 Ruby 对象的属性

Ruby注入初始为哈希

Jekyll - 找不到命令

在 ruby​​ 的超类中调用另一个方法

如何判断变量是数字还是字符串?

Ruby哈希中的条件键/值

使用哈希值呈现 ERB 模板

使用正则表达式进行 Ruby Electron邮件验证

常见的 Ruby 习语

如何创建一个 Gemfile?