0

attribute1とattribute3の値のみを抽出したい。私の場合、他の属性を「スキップ」するために文字セットが機能しないように見える理由がわかりません(attribute3は私が望むように抽出されません):

content: {<tag attribute1="valueattribute1" attribute2="valueattribute2" attribute3="valueattribute3">
</tag>
<tag attribute2="valueattribute21" attribute1="valueattribute11" >
</tag>
}


attribute1: [{attribute1="} copy valueattribute1 to {"} thru {"}]
attribute3: [{attribute3="} copy valueattribute3 to {"} thru {"}]

spacer: charset reduce [tab newline #" "]
letter: complement spacer 
to-space: [some letter | end]

attributes-rule: [(valueattribute1: none valueattribute3: none) [attribute1 | none] any letter [attribute3 | none] (print valueattribute1 print valueattribute3)
| [attribute3 | none] any letter [attribute1 | none] (print valueattribute3 print valueattribute1
valueattribute1: none valueattribute3: none
)
| none
]

rule: [any [to {<tag } thru {<tag } attributes-rule {>} to {</tag>} thru {</tag>}] to end]

parse content rule

出力は

>> parse content rule
valueattribute1
none
== true
>>
4

3 に答える 3

1

簡単に言えば、[任意の文字]はあなたのattribute3 = "..."を食べます。# "^" "文字はあなたの定義によると'文字です。さらに、attribute2がない場合、一般的な2番目の属性ルールで問題が発生する可能性があります。 attribute3を食べ、attribute3ルールには一致するものがありません-オプションのattribute2またはオプションのanything-but-attribute3があることを明示する方が良いです

attribute1="foo"       attribute2="bar" attribute3="foobar" 
<- attribute1="..." -> <-     any letter                 -> <- attibute3="..." ->

また、'/ allリファインメントなしで解析すると、スペースが無視されます(または、スペースが関係する場合は、少なくとも非常に扱いにくいです)-このタイプの解析には、/allを強くお勧めします。

于 2010-03-13T14:15:03.610 に答える
1

まず、を使用していませんparse/all。Rebol 2では、これは、解析が実行される前に空白が効果的に削除されたことを意味します。これはRebol3では当てはまりません。解析ルールがブロック形式の場合(ここで行っているように)、/all暗黙的に示されます。

(注:Rebol 3は、これらの「最小限の」解析シナリオの関数を優先して、非ブロック形式の解析ルールを破棄するというコンセンサスがあったようです。これにより、完全に削除されます。まだアクションは実行されていません。残念ながら、これです。)split/all

第二に、あなたのコードにはバグがあり、私はそれを整理するのに時間を費やすつもりはありません。(これは主に、Rebolの解析を使用してXML / HTMLを処理するのはかなりばかげた考えだと思うからです:P)

ただし、重要なツールがあることを忘れないでください。解析ルールでset-wordを使用すると、解析位置が変数にキャプチャされます。次に、それを印刷して、現在の場所を確認できます。attribute-rule最初に言う場所の部分を変更すると、次のように表示any letterされpos: (print pos) any letterます。

>> parse/all content rule
 attribute2="valueattribute2" attribute3="valueattribute3">
</tag>
<tag attribute2="valueattribute21" attribute1="valueattribute11" >
</tag>

valueattribute1
none
== true

先頭のスペースが表示されますか?直前のあなたのルールany letterはあなたをスペースに置きます...そしてあなたがどんな手紙でも大丈夫だと言ったので、どんな手紙も大丈夫ではなく、そしてすべてが捨てられます。

(注:Rebol 3には、さらに優れたデバッグツールがあります...単語??。これを解析ブロックに入れると、現在処理しているトークン/ルールと入力の状態がわかります。このツールを使用すると、何が起こっているのかをより簡単に見つけることができます:

>> parse "hello world" ["hello" ?? space ?? "world"]
space: " world"
"world": "world"
== true

...現在、r3 mac intelでは本当にバグがあります。)

さらに、使用していない場合copyは、のパターンto X thru Xは不要ですが、を使用するだけでそれを実現できますthru X。コピーを作成したい場合は、ブリーフでそれを行うこともできます。copy Y to X Xまたは、それが単一の記号である場合は、よりクリアなものを書くことができます。copy Y to X skip

繰り返しコードを書いているのを目にする場所では、Rebolは次のように使用することで上記のステップに進むことができることを覚えておいてくださいcompose

>> temp: [thru (rejoin [{attribute} num {=}]) 
          copy (to-word rejoin [{valueattribute} num]) to {"} thru {"}]

>> num: 1
>> attribute1: compose temp
== [thru "attribute1=" copy valueattribute1 to {"} thru {"}]

>> num: 2
>> attribute2: compose temp
== [thru "attribute2=" copy valueattribute2 to {"} thru {"}]
于 2010-03-13T16:22:48.557 に答える
0

parse / allを追加しても、何も変更されていないようです。最後に、これは機能しているようです(set-wordを使用すると、デバッグに非常に役立ちます!!!)、どう思いますか?

content: {<tag attribute1="valueattribute1" attribute2="valueattribute2" attribute3="valueattribute3">
</tag>
<tag attribute2="valueattribute21" attribute1="valueattribute11" >
</tag>
}


attribute1: [to {attribute1="} thru {attribute1="} copy valueattribute1 to {"} thru {"}]
attribute3: [to {attribute3="} thru {attribute3="} copy valueattribute3 to {"} thru {"}]

letter: charset reduce ["ABCDEFGHIJKLMNOPQRSTUabcdefghijklmnopqrstuvwxyz1234567890="]

attributes-rule: [(valueattribute1: none valueattribute3: none) 
[attribute1 | none] any letter pos: 
[attribute3 | none] (print valueattribute1 print valueattribute3)
| [attribute3 | none] any letter [attribute1 | none] (print valueattribute3 print valueattribute1
valueattribute1: none valueattribute3: none
)
| none
]

rule: [any [to {<tag } thru {<tag } attributes-rule {>} to {</tag>} thru {</tag>}] to end]

parse content rule

出力:

>> parse/all content rule
valueattribute1
valueattribute3
valueattribute11
none
== true
>>
于 2010-03-13T18:26:23.897 に答える