ruby - 我如何在 Ruby 中标记这个字符串?

标签 ruby parsing tokenize text-parsing

我有这个字符串:

%{Children^10 Health "sanitation management"^5}

我想将其转换为将其标记为哈希数组:

[{:keywords=>"children", :boost=>10}, {:keywords=>"health", :boost=>nil}, {:keywords=>"sanitation management", :boost=>5}]

我知道 StringScanner 和 Syntax gem但我找不到足够的代码示例。

有什么建议吗?

最佳答案

对于真正的语言,词法分析器是必经之路 - like Guss said .但是如果完整的语言只是和你的例子一样复杂,你可以使用这个快速 hack:

irb> text = %{Children^10 Health "sanitation management"^5}
irb> text.scan(/(?:(\w+)|"((?:\\.|[^\\"])*)")(?:\^(\d+))?/).map do |word,phrase,boost|
       { :keywords => (word || phrase).downcase, :boost => (boost.nil? ? nil : boost.to_i) }
     end
#=> [{:boost=>10, :keywords=>"children"}, {:boost=>nil, :keywords=>"health"}, {:boost=>5, :keywords=>"sanitation management"}]

如果您正在尝试解析常规语言,那么此方法就足够了 - 尽管使语言变得非常规并不需要更多的复杂性。

正则表达式的快速分解:

  • \w+ 匹配任何单词关键词
  • (?:\\.|[^\\"]])* 使用非捕获括号 ((?:...)) 来匹配转义双引号字符串的内容 - 转义符号(\n\"\\ 等)或任何单个字符那不是转义符号或结束引号。
  • "((?:\\.|[^\\"]])*)" 仅捕获引用关键字短语的内容。
  • (?:(\w+)|"((?:\\.|[^\\"])*)") 匹配任何关键字 - 单个术语或短语,捕获单个术语放入$1 并将短语内容放入$2
  • \d+ 匹配一个数字。
  • \^(\d+) 捕获插入符号 (^) 后的数字。由于这是第三组捕获括号,它将被捕获到 $3
  • (?:\^(\d+))? 捕获插入符号后的数字(如果有),否则匹配空字符串。

String#scan(regex) 尽可能多次将正则表达式与字符串匹配,输出“匹配”数组。如果正则表达式包含捕获括号,则“匹配项”是捕获的项目数组 - 因此 $1 变为 match[0]$2 变为 match[1] 等。任何未与部分字符串匹配的捕获括号都映射到结果“匹配”中的 nil 条目。

#map 然后获取这些匹配项,使用一些 block 魔术将每个捕获的术语分解为不同的变量(我们可以做 do |match| ; word,phrase,boost = * match),然后创建你想要的散列。 wordphrase 中的一个将是 nil,因为两者都无法与输入匹配,所以 (word || phrase) 将返回非nil 的,而#downcase 会将其转换为全部小写。 boost.to_i 将字符串转换为整数,而 (boost.nil? ? nil : boost.to_i) 将确保 nil 提升保持不变

关于ruby - 我如何在 Ruby 中标记这个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/713559/

相关文章:

ruby-on-rails - Rails 4 迁移 : how to reorder columns

使用 NameSpace 解析 XML

python - 用 Python 解析文本 : unstructured but similar information with different formatting

ios - 在另一个类的一个 ViewController 的 TableView 上调用 reloadData 的正确方法是什么?

xaml - 使用收件人、抄送和密件抄送时,如何为 Outlook 中已知的 UWP 创建标记化控件

elasticsearch - ElasticSearch:尝试获取专有名称的拼写建议

ruby - JSON 解析编码错误

ruby-on-rails - sudo gem install pg 不起作用

python - 在 Python 中标记代码块

ruby-on-rails - 如何正确使用模拟?