ruby - Ruby 动态填充 2 个 dim 数组
问题描述
我正在使用解析器来分析 SQL 代码,因此试图处理所有块注释。我提出了按索引处理正则表达式的解决方案,以查看它是否在注释块内,并为此尝试在下面的代码中填充 2 dim 数组,其中第二个元素将是字面意思,让我们说s。不确定这是否可行。我尝试了一颗宝石,但失败了。我的目标是让数组充满
all =[[9,'s'],[19,'s'],[24,'s']]
参考下面的例子。最终目标是处理遗留的 SQL 代码(很多......)以找到具有特定关键字的活动行。最好的
x = 'line:xss /* */ /* /* CODE_Comment */ '
puts x
i = -1
all = [[],[]]
while i = x.index('/*',i+1)
do all << i ####<@>>< how to add literal to second element ???
end
puts all
解决方案
您可以执行以下操作。
str = 'line:xss /* */ /* /* CODE_Comment */ '
str.gsub(/\/\*/).with_object([]) { |_,a| a << [Regexp.last_match.begin(0), 's'] }
#=> [[9, "s"], [19, "s"], [24, "s"]]
步骤如下。
enum1 = str.gsub(/\/\*/)
#=> #<Enumerator: "line:xss /* */ /* /* CODE_Comment */ "
# :gsub(/\/\*/)>
如果您检查String#gsub的文档,您将看到当gsub
有单个参数且没有块(该方法的第 4种形式)时,它返回一个枚举器。奇怪的是,当以这种方式使用时,它与用其他子字符串替换子字符串无关。
enum1
无非就是生成匹配:
enum1.next #=> "/*"
enum1.next #=> "/*"
enum1.next #=> "/*"
enum1.next #=> StopIteration (iteration reached an end)
请参阅Enumerator#next。在继续之前,让我们重置枚举器:
enum1.rewind
请参阅Enumerator#rewind。下一个,
enum2 = enum1.with_object([])
#=> #<Enumerator: #<Enumerator: "line:xss /* */ /* /* CODE_Comment */ "
# :gsub(/\/\*/)>:with_object([])>
enum2.next #=> ["/*", []]
enum2.next #=> ["/*", []]
enum2.next #=> ["/*", []]
enum2.next #=> StopIteration (iteration reached an end)
enum2.rewind
enum2
(可以被认为是一个复合枚举器)现在生成它传递给块的元素。这些元素的值由块变量捕获,然后执行块计算。我们可以添加一些puts
语句来检查计算的值。
enum2.each do |_,a|
puts "\n_ = #{_}, a = #{a}"
md = Regexp.last_match
b= md.begin(0)
puts "md = #{md}, b = #{b}"
a << [b, 's']
puts "a = #{a}"
end
#=> [[9, "s"], [19, "s"], [24, "s"]]
并打印
_ = /*, a = []
md = /*, b = 9
a = [[9, "s"]]
_ = /*, a = [[9, "s"]]
md = /*, b = 19
a = [[9, "s"], [19, "s"]]
_ = /*, a = [[9, "s"], [19, "s"]]
md = /*, b = 24
a = [[9, "s"], [19, "s"], [24, "s"]]
我使用下划线(一个有效的局部变量)作为第一个块变量的占位符,向读者表明它没有用于块计算(一种常用的约定)。要构造数组,我们需要进行str
匹配的字符串中的偏移量。为此,我们首先获取该MatchData
匹配生成的实例(参见Regexp::last_match),然后使用LastMatch#begin方法获取匹配开始的偏移量。最后,我们将所需的 2 元素数组附加到a
.
的值Regexp.last_match
由全局变量 保存$~
,因此有时使用该变量代替Regexp.last_match
。
推荐阅读
- java - HotSwapAgent 无法将 filePath 转换为 classPathPath
- php - Laravel 应用到 Phar
- python - 如何使用 python 检查并在文件的每一行中插入缺失的变量?
- firebase - Firebase 动态链接不会在社交媒体中预览图片
- variables - Visual-C++ Win32 C++ 应用程序。如何将变量打印到主屏幕?
- java - 当我将 0 加到一个数字上时,结果始终为零。其他数字没问题
- reactjs - 可以连接 PureComponent 吗?
- ffmpeg - ffmpeg 可以等到新的输入吗?
- linux - 在 Linux 服务器上运行 mongodb 时出错
- c# - 在 ASP.NET 核心中绑定源参数推断