私は立ち往生しています。数日間、このテキストを解析しようとしていました(下部を見てください)。しかし、いくつかのことを理解することはできません。まず、テキストは固定幅の列を持つツリー構造でフォーマットされますが、正確な列幅は最も広いフィールドによって異なります。
私はrubyを使用しています。最初は、Treetop gemを試し、ある程度の進歩を遂げましたが、Parsletを試すことにしたので、今使っているので、使いやすいようですが、詳細なドキュメントを見つけるのは難しいです。
現在、各行を個別に解析し、解析されたエントリを使用して配列を作成していますが、構造が緩んでいるため、これは正しくありません。それを再帰的に解析し、深さを処理する必要があります。
ヒント、アイデア、提案をいただければ幸いです。
これが私の現在のコードです。動作しますが、すべてのデータがフラット化されます。私の現在の考えは、現在の行の開始位置が前の行の開始位置(つまり幅)よりも大きい場合に再帰的に解析することです。したがって、より深いレベルに進む必要があることを意味します。実はなんとかできたのですが、きちんと外に出られなかったので、そのコードを削除しました。
require 'pp'
require 'parslet'
require 'parslet/convenience'
class TextParser < Parslet::Parser
@@width = 5
root :text
rule(:text) { (line >> newline).repeat }
rule(:line) { left >> ( topline | subline ).as(:entry) }
rule(:topline) {
float.as(:number) >> str('%') >> space >> somestring.as(:string1) >> space >> specialstring.as(:string2) >> space >> specialstring.as(:string3)
}
rule(:subline) {
dynamic { |source, context|
width = context.captures[:width].to_s.length
width = width-1 if context.captures[:width].to_s[-1] == '|'
if width > @@width
# should be recursive
result = ( specialline | lastline | otherline | empty )
else
result = ( specialline | lastline | otherline | empty )
end
@@width = width
result
}
}
rule(:otherline) {
somestring.as(:string1)
}
rule(:specialline) {
float.as(:number) >> str('%') >> dash >> space? >> specialstring.as(:string1)
}
rule(:lastline) {
float.as(:number) >> str('%') >> dash >> space? >> str('[...]')
}
rule(:empty) {
space?
}
rule(:left) { seperator.capture(:width) >> dash?.capture(:dash) >> space? }
rule(:somestring) { match['0-9A-Za-z\.\-'].repeat(1) }
rule(:specialstring) { match['0-9A-Za-z&()*,\.:<>_~'].repeat(1) }
rule(:space) { match('[ \t]').repeat(1) }
rule(:space?) { space.maybe }
rule(:newline) { space? >> match('[\r\n]').repeat(1) }
rule(:seperator) { space >> (str('|') >> space?).repeat }
rule(:dash) { space? >> str('-').repeat(1) }
rule(:dash?) { dash.maybe }
rule(:float) { (digits >> str('.') >> digits) }
rule(:digits) { match['0-9'].repeat(1) }
end
parser = TextParser.new
file = File.open("text.txt", "rb")
contents = file.read.to_s
file.close
pp parser.parse_with_debug(contents)
テキストは次のようになります(https://gist.github.com/davispuh/4726538)
1.23% somestring specialstring specialstring
|
--- specialstring
|
|--12.34%-- specialstring
| specialstring
| |
| |--12.34%-- specialstring
| | specialstring
| | |
| | |--12.34%-- specialstring
| | --1.12%-- [...]
| |
| --2.23%-- specialstring
| |
| |--12.34%-- specialstring
| | specialstring
| | specialstring
| | |
| | |--12.34%-- specialstring
| | | specialstring
| | | specialstring
| | --1.23%-- [...]
| |
| --1.23%-- [...]
|
--1.05%-- [...]
1.23% somestring specialstring specialstring
2.34% somestring specialstring specialstring
|
--- specialstring
specialstring
specialstring
|
|--23.34%-- specialstring
| specialstring
| specialstring
--34.56%-- [...]
|
--- specialstring
specialstring
|
|--12.34%-- specialstring
| |
| |--100.00%-- specialstring
| | specialstring
| --0.00%-- [...]
--23.34%-- [...]
ありがとう :)