最快的方式做很多不同的gsub操作?

时间:2012-05-23 17:11:39

标签: ruby regex gsub

我正在将数万个文档从一种标记格式(显然是RUNOFF的一些后代,我有很少的文档)转换成我可以提供给LaTeX的东西。此过程的一部分涉及在每个文档中搜索旧标记格式中具有特殊含义的每个字符串,并将其替换为LaTeX的相应字符串。这些有数百种。到目前为止我的两个想法是将每个作为一个单独的gsub或者使用正则表达式创建一个gsub,它将匹配(通过ORing)许多符号,然后将匹配传递给带有大型case语句的方法支持适当的替代。从表面上看,第二种方式减少了每个文档必须扫描的次数,但正则表达式中OR的开销可能更昂贵。有没有人知道哪种方法更好,或者我错过了一个好方法?

以下是我描述的两种方式的示例。它们可能不完美。试图明白我的观点。

方法1:

output.gsub!(/a<-"/, '\\"{a}') # ä
output.gsub!(/a<-^/, '\\^{a}') # â
output.gsub!(/a<-~/, '\\~{a}') # ã
...etc

方法2:

output.gsub!(/a<-"|a<-^|a<-~|etc/) {|match| convert_symbol(match)}

def convert_symbol(input)
  case match
  when 'a<-"'
    '\\"{a}' # ä
  when "a<-^"
    '\\^{a}' # â
  when "a<-~"
    '\\~{a}' # ã
  when 'etc'
    '\\LaTeX...etc'
  end
end

3 个答案:

答案 0 :(得分:8)

哇,那是很多文件。但我想如果我这样做,我不会担心程序的效率如何。计算机快速而便宜,不介意整夜运行。

实际上,我不认为我会在一般情况下打开代码(连接到程序中)正则表达式。我想我会将替换放入平面或YAML文件中,并且只在程序中构建需要状态的表达式或功能。

因此,如果我需要记住一个令牌,我可能会在其中构建表达式,或者可能在填充了转码表达式的YAML文件中将其标记出来......我最担心的是我的程序结构的好坏程度。我会尽量减少摆弄它并运行测试的时间,至少在开始时不要担心它的运行速度。

特别是,该程序一旦完成,每个文档只运行一次。因此,对于仔细的速度优化来说,它并不是一个很好的候选者。此外,由于它只运行一次而你必须永远忍受其决定,我认为你的重点应该是保真而不是速度。

答案 1 :(得分:6)

{ /a<-"/ => '\\"{a}', 
  ... 
}.each { |find, replace| output.gsub! find, replace }

答案 2 :(得分:0)

这些是一般格式吗?然后你可以简单地

output.gsub!(/([aeiouy])<-(["~^])/, '\\\2{\1}')

...假设Ruby在\1\2等方面有反向引用(抱歉,对语言不太熟悉)。

相关问题