2009-12-09 5 views
1

Je suis en train d'analyser un fichier texte et je souhaite pouvoir étendre les ensembles de jetons facilement reconnaissables. Actuellement, j'ai ce qui suit:Ruby paramétrer si ... puis bloque

if line =~ /!DOCTYPE/ 
    puts "token doctype " + line[0,20] 
    @ast[:doctype] << line 
    elsif line =~ /<html/ 
    puts "token main HTML start " + line[0,20] 
    html_scanner_off = false 
elsif line =~ /<head/ and not html_scanner_off 
    puts "token HTML header starts " + line[0,20] 
    html_header_scanner_on = true 
    elsif line =~ /<title/ 
    puts "token HTML title " + line[0,20] 
    @ast[:HTML_header_title] << line 
    end 

Existe-t-il un moyen d'écrire ceci avec un bloc de rendement, par ex. quelque chose comme:

 
scanLine("title", :HTML_header_title, line) 

?

Répondre

2

Don't parse HTML with regexes.

Cela mis à part, il y a plusieurs façons de le faire ce que vous parlez. Un:

class Parser 
     class Token 
       attr_reader :name, :pattern, :block 
       def initialize(name, pattern, block) 
         @name = name 
         @pattern = pattern 
         @block = block 
       end 

       def process(line) 
         @block.call(self, line) 
       end 
     end 

     def initialize 
       @tokens = [] 
     end 

     def scanLine(line) 
       @tokens.find {|t| line =~ t.pattern}.process(line) 
     end 

     def addToken(name, pattern, &block) 
       @tokens << Token.new(name, pattern, block) 
     end 
end 

p = Parser.new 
p.addToken("title", /<title/) {|token, line| puts "token #{token.name}: #{line}"} 
p.scanLine('<title>This is the title</title>') 

Cela a des limites (pas comme la vérification des jetons en double), mais fonctionne:

parser.rb $ ruby ​​
titre symbolique: <titre> Ceci est le titre </titre >
$

+0

super! merci pour le point d'entrée à la méta-programmation ... pour les autres, cette présentation aide aussi à comprendre quelle est l'idée: http://www.slideshare.net/faro00oq/metaprogramming-with-ruby – poseid

2

Si vous avez l'intention d'analyser du contenu HTML, vous pouvez utiliser l'un des analyseurs HTML comme nokogiri (http://nokogiri.org/) ou Hpricot (http://hpricot.com/) qui sont vraiment de haute qualité. Une approche "roll-your-own" prendra probablement plus de temps pour se perfectionner que de trouver comment utiliser l'un de ces analyseurs. D'autre part, si vous avez affaire à quelque chose qui n'est pas tout à fait HTML, et qui ne peut pas être analysé de cette façon, vous aurez besoin de rouler les vôtres d'une manière ou d'une autre. Il y a quelques frameworks d'analyseur Ruby qui peuvent vous aider, mais pour les tâches simples où la performance n'est pas un facteur critique, vous pouvez vous débrouiller avec une pile d'expressions rationnelles comme celle que vous avez ici.

Questions connexes