如何用REBOL解析HTML标签内部?

时间:2011-06-17 15:44:30

标签: parsing rebol

我有一个我加载了加载/标记的网页。我需要解析一堆东西,但有些数据在标签中。我可以解析它的任何想法?以下是我到目前为止(并尝试过)的样本:

REBOL []

mess: {
<td>Bob Sockaway</td>
<td><a href=mailto:bsockaway@example.com>bsockaway@example.com</a></td>
<td>9999</td>
}

rules: [
    some [
        ; The expression below /will/ work, but is useless because of specificity.
        ; <td> <a href=mailto:bsockaway@example.com> s: string! </a> (print s/1) </td> | 

        ; The expression below will not work, because <a> doesn't match <a mailto=...>
        ; <td> <a> s: string! </a> (print s/1) </td> |

        <td> s: string! (print s/1) </td> |

        tag! | string! ; Catch any leftovers.
    ]
]

解析加载/标记混乱规则

这会产生:

Bob Sockaway
9999

我希望看到更像是:

Bob Sockaway
bsockaway@example.com
9999

有什么想法?谢谢!

请注意!为了它的价值,我想出了一个很好的简单规则集,它将获得理想的结果:

rules: [
    some [
        <td> any [tag!] s: string! (print s/1) any [tag!] </td> |
        tag! | string! ; Catch any leftovers.
    ]
]

2 个答案:

答案 0 :(得分:2)

使用mess处理LOAD/MARKUP时,您会得到此信息(我已对其进行格式化+评论):

[
    ; string!
    "^/" 

    ; tag! string! tag!
    <td> "Bob Sockaway" </td>

    ; string!
    "^/"

    ; tag! tag!
    ;     string!
    ; tag! tag!
    <td> <a href=mailto:bsockaway@example.com>
        "bsockaway@example.com"
    </a> </td>

    ; (Note: you didn't put the anchor's href in quotes above...)

    ; string!
    "^/"

    ; tag! string! tag!
    <td> "9999" </td> 

    ; string!
    "^/"
]

您的输出模式与[<td> string! </td>]形式的系列匹配,但不匹配[<td> tag! string! tag! </td>]形式的内容。不管你的标题中提出的问题,你可以用几种方式解决这个特殊的困境。一种可能是保持计数是否在TD标签内,并在计数非零时打印任何字符串:

rules: [
    (td-count: 0)
    some [
        ; if we see an open TD tag, increment a counter
        <td> (++ td-count)
        |
        ; if we see a close TD tag, decrement a counter
        </td> (-- td-count)
        |
        ; capture parse position in s if we find a string
        ; and if counter is > 0 then print the first element at
        ; the parse position (e.g. the string we just found) 
        s: string! (if td-count > 0 [print s/1])
        |
        ; if we find any non-TD tags, match them so the
        ; parser will continue along but don't run any code
        tag!
    ]
]

这会产生您要求的输出:

Bob Sockaway
bsockaway@example.com
9999

但是,您基本上也想知道是否可以在同一组规则中转换为块解析的字符串解析(不会跳转到开放代码中)。我调查了它“混合解析”看起来它可能是Rebol 3中解决的一个功能。但是,我无法让它在实践中发挥作用。所以我问了一个我自己的问题。

How to mix together string parsing and block parsing in the same rule?

答案 1 :(得分:1)

我想我找到了一个很好的解决方案。如果你有许多不同的标签,你可能需要进行概括。

我正在寻找查询标记的id属性!:

3

在tag!的解析规则中,我这样做了:

<query id="5">

要查看更多标签,我会使用案例。也许最好设置_qid

  | set t tag! (
    p: make block! t 
    if p/1 = 'query [_qid: to-integer p/3]
  )

我最终需要解析另一个标签,这是一个很好的通用模式

to-integer select p 'id=