我想使用正则表达式从像这样的字符串中创建一个结果数组:
results|foofoofoo\nresults|barbarbarbar\nresults|googoogoo\ntimestamps||friday
这是我现在的正则表达式。它适用于Sublime Text的正则表达式搜索,但不适用于Ruby:
(results)\|.*?\\n(?=((results\|)|(timestamps\|\|)))
这将是理想的结果:
1. results|foofoofoo
2. results|barbarbar
3. results|googoogoo
相反,我得到了这些奇怪的回报,我无法理解。为什么这不选择结果行?
Match 1
1. results
2. results|
3. results|
4.
Match 2
1. results
2. results|
3. results|
4.
Match 3
1. results
2. timestamps||
3.
4. timestamps||
以下是使用正则表达式的实际代码:
#create new lines for each regex'd line body with that body set as the raw attribute
host_scan.raw.scan(/(?:results)\|.*?\\n(?=((?:results\|)|(?:timestamps\|\|)))/).each do |body|
@lines << Line.new({:raw => body})
end
答案 0 :(得分:1)
作为Kendall Frey already stated,您创建了太多的捕获组。无需对第一个文字“结果|”进行分组,也无需将备用组的元素分组到单个非反向引用组中。你打算做的是这个正则表达式:
/results\|.*?(?=\\n(?:results\||timestamps\|\|))/
或者,如果您不介意重复\\n
部分,则可以取消非捕获子组:
/results\|.*?(?=\\nresults\||\\ntimestamps\|\|)/
- 两者都会返回问题中指定的匹配值数组。
答案 1 :(得分:0)
我猜这与捕捉群组有关。如果您将所有(...)
更改为(?:...)
,则会消除捕获组。
答案 2 :(得分:0)
使用split("\n")
,而不是跳转到正则表达式,这是获取数据的一种更复杂的方法。
text = "results|foofoofoo\nresults|barbarbarbar\nresults|googoogoo\ntimestamps||friday"
ary = text.split("\n")
ary
是:
[
"results|foofoofoo",
"results|barbarbarbar",
"results|googoogoo",
"timestamps||friday"
]
切片,你可以得到:
ary[0..2]
=> ["results|foofoofoo", "results|barbarbarbar", "results|googoogoo"]
编辑:
基于注释,字符串中有更多回车符和复杂字符:
require 'awesome_print'
text = "results|foofoofoo\nmorefoo\nandevenmorefoo\nresults|barbarbarbar\nandmorebar\nandyetagainmorebar\nresults|googoogoo\ntimestamps||friday"
ap text.sub(/\|\|friday$/, '').split('results')[1..-1].map{ |l| 'results' << l }
哪个输出:
[
[0] "results|foofoofoo\nmorefoo\nandevenmorefoo\n",
[1] "results|barbarbarbar\nandmorebar\nandyetagainmorebar\n",
[2] "results|googoogoo\ntimestamps"
]
答案 3 :(得分:0)
答案结果是在括号中。用括号括起来会使它返回整个匹配而不仅仅是尾部分隔符。
host_scan.raw.scan(/((?:results\|.*?\\n)(?=(?:results\|)|(?:timestamps\|\|)))/).each do |body|
@lines << Line.new({:raw => body})
end