2011-08-08 3 views
2

Ruby에서 태그 (속성 포함)와 텍스트의 문자 수를 계산하려면 HTML 문서를 구문 분석해야합니다. 성능상의 이유로 DOM 파서를 사용하고 싶지 않습니다. Nokogiri의 SAX 및 Reader 파서와 SaxMachine을 살펴 보았지만 어느 것도 입력 HTML에서 파서의 위치를 ​​추적 할 수있는 방법을 제공하지 못합니다.Ruby에서 HTML 문서의 태그 및 텍스트 문자 계산하기

누구든지 Ruby에서이 정보에 액세스하는 방법을 알고 있습니까? 미리 감사드립니다

+0

제 질문에 더 정확하게 말하면 모든 HTML 문자와 모든 텍스트를 계산해야하지만 텍스트가 들어있는 태그를 알아야합니다. 더욱이 앞으로는 처리해야하는 태그를 필터링해야 할 것입니다. – pablochacin

+0

우리는 실제로 솔루션을 설계 할 수 없습니다. 요구 사항은 여전히 ​​모호합니다. 당신이 목표로 삼고있는 결과물의 예를 제시 할 수 있습니까? –

+0

다른 해결책을 제시했습니다. 찾고있는 것에 더 가깝습니까? –

답변

5

입력 문자열

html = <<-HTML 
<html> 

<head> 
    <title>Title</title> 
</head> 

<body> 
    Hello world! 
</body> 

</html> 
HTML 

벙어리 솔루션

원유 솔루션은 모든 알파벳 문자 (4 자에 대한 예. </html> 수를) 계산합니다.

tag_count = 0 
text_count = 0 

in_tag = false 

html.each_char do |char| 
    case char 
    when '<' 
    in_tag = true 
    when '>' 
    in_tag = false 
    when /\w/ 
    in_tag ? tag_count += 1 : text_count += 1 
    end 
end 

puts "Text char count: #{text_count}" 
puts "Tag char count: #{tag_count}" 

노코 기리 SAX 솔루션은

이것은 쉽게 다른 언어 (예. 자바)로 변환 할 수있다.

require 'nokogiri' 

class HtmlCounter < Nokogiri::XML::SAX::Document 

    attr_accessor :tag_count, :text_count, :comment_count 

    def initialize(filtered_tags = []) 
    @filtered_tags = filtered_tags 
    end 

    def start_document 
    @tag_count = Hash.new(0) 
    @text_count = Hash.new(0) 
    @comment_count = 0 
    @current_tags = [] 
    end 

    def start_element(name, attrs) 
    # Keep track of the nesting 
    @current_tags.push(name) 

    if should_count? 
     # Count the end element as well 
     count_tag(name.length * 2) 
     count_tag(attrs.flatten.map(&:length).inject(0) {|sum, length| sum + length}) 
    end 
    end 

    def end_element(name) 
    @current_tags.pop 
    end 

    def comment(string) 
    count_comment(string.length) if should_count? 
    end 

    def characters(string) 
    count_text(string.strip.length) if should_count? 
    end 

    def should_count? 
    # Are we in a filtered tag ? 
    (@current_tags & @filtered_tags).empty? 
    end 

    def count_text(count) 
    @text_count[@current_tags.last] += count 
    end 

    def count_tag(count) 
    @tag_count[@current_tags.last] += count 
    end 

    def count_comment(count) 
    @comment_count[@current_tags.last] += count 
    end 
end 

# Don't count things in title tags 
counter = HtmlCounter.new(["title"]) 
parser = Nokogiri::HTML::SAX::Parser.new(counter) 
parser.parse(html) 

puts "Text char count: #{counter.text_count}" 
puts "Tag char count: #{counter.tag_count}" 

출력 :이 도움이

Text char count: {"body"=>12} 
Tag char count: {"html"=>8, "head"=>8, "body"=>8} 

희망.