我正在使用 RUBY 的正则表达式处理文本,例如
${1:aaa|bbbb}
${233:aaa | bbbb | ccc ccccc }
${34: aaa | bbbb | cccccccc |d}
${343: aaa | bbbb | cccccccc |dddddd ddddddddd}
${3443:a aa|bbbb|cccccccc|d}
${353:aa a| b b b b | c c c c c c c c | dddddd}
我想在每条管道之间获取trimed文本。例如,对于我上面示例的第一行,我想得到结果 aaa 和 bbbb ,对于第二行,我想要 aaa , bbbb 和 ccc ccccc 。现在我已经编写了一段正则表达式和一段ruby代码来测试它:
array = "${33:aaa|bbbb|cccccccc}".scan(/\$\{\s*(\d+)\s*:(\s*[^\|]+\s*)(?:\|(\s*[^\|]+\s*))+\}/)
puts array
现在我的问题是(?:\|(\s*[^\|]+\s*))+
部分无法创建多个组。我不知道如何解决这个问题,因为每行所需的文本数量是可变的。有人可以帮忙吗?
答案 0 :(得分:1)
你为什么不分裂你的字符串?
str = "${233:aaa | bbbb | ccc ccccc }"
str.split(/\d+|\$|\{|\}|:|\|/).select{|v| !v.empty? }.select{|v| !v.empty? }.map{|v| v.strip}.join(', ')
#=> "aaa, bbb, cc cccc"
答案 1 :(得分:1)
而不是试图一次完成所有事情,分而治之:
DATA.each do |line|
line =~ /:(.+)\}/
items = $1.strip.split( /\s* \| \s*/x )
p items
end
__END__
${1:aaa|bbbb}
${233:aaa | bbbb | ccc ccccc }
${34: aaa | bbbb | cccccccc |d}
${343: aaa | bbbb | cccccccc |dddddd ddddddddd}
${3443:a aa|bbbb|cccccccc|d}
${353:aa a| b b b b | c c c c c c c c | dddddd}
如果您想使用单个正则表达式执行此操作,可以使用scan
,但这似乎更难以理解:
DATA.each do |line|
items = line.scan( /[:|] ([^|}]+) /x ).flatten.map { |i| i.strip }
p items
end
答案 2 :(得分:1)
这可能对您有所帮助
a = [
'${1:aaa|bbbb}',
'${233:aaa | bbbb | ccc ccccc }',
'${34: aaa | bbbb | cccccccc |d}',
'${343: aaa | bbbb | cccccccc |dddddd ddddddddd}',
'${3443:a aa|bbbb|cccccccc|d}',
'${353:aa a| b b b b | c c c c c c c c | dddddd}'
]
a.each do |input|
puts input
input.scan(/[:|]([^|}]+)/).flatten.each do |s|
puts s.gsub(/(^\s+|\s+$)/, '') # trim
end
end
${1:aaa|bbbb}
aaa
bbbb
${233:aaa | bbbb | ccc ccccc }
aaa
bbbb
ccc ccccc
${34: aaa | bbbb | cccccccc |d}
aaa
bbbb
cccccccc
d
${343: aaa | bbbb | cccccccc |dddddd ddddddddd}
aaa
bbbb
cccccccc
dddddd ddddddddd
${3443:a aa|bbbb|cccccccc|d}
a aa
bbbb
cccccccc
d
${353:aa a| b b b b | c c c c c c c c | dddddd}
aa a
b b b b
c c c c c c c c
dddddd
答案 3 :(得分:1)
当您在正则表达式中重复捕获组时,捕获组仅存储与其上一次迭代匹配的文本。如果需要捕获多次迭代,则需要使用多个正则表达式。 (.NET是唯一的例外。它的CaptureCollection
提供捕获组的所有迭代的匹配。)
在您的情况下,您可以进行搜索和替换,以便无需替换^\d+:
。这会剥掉字符串开头的数字和冒号。然后使用正则表达式split()
调用\s*\|\s*
将字符串拆分为由竖线分隔的元素。