0

私はexpect/TCLの初心者であり、以下のような出力をしたHTMLページを解析しようとしています。

<li><p>Timestamp: Wed, 14 Nov 2012 16:37:50 -0800
<li><p>Your IP address: 202.76.243.10</p></li>
<li><p class="XXX_no_wrap_overflow_hidden">Requested URL: /</p></li>
<li><p>Error reference number: 1003</p></li>
<li><p>Server ID: FL_23F7</p></li>
<li><p>Process ID: PID_1352939870.809-1-428432242</p></li>
<li><p>User-Agent: </p></li>

私のスクリプトは以下のとおりです。「YourIPaddress:」という行を解析できないWebページを取得できます。これにより、エラーが発生します。

#!/usr/bin/expect -f
set timeout -1
spawn telnet www.whatismyip.com 80
send "GET /\r\n"
expect
set output $expect_out(buffer)
foreach line [split $output \n] {
        regexp {.*<li><p>Your IP Address Is:.*?(\d+\.\d+\.\d+\.\d+)} $line ip
        if {[string length ${ip}]} {
                puts $ip
    }
}

エラーは次のとおりです。

    Connection closed by foreign host.
can't read "ip": no such variable
    while executing
"string length ${ip}"
    ("foreach" body line 3)
    invoked from within
"foreach line [split $output \n] {
        regexp {.*<li><p>Your IP Address Is:.*?(\d+\.\d+\.\d+\.\d+)} $line ip
        if {[string length ${ip}]} {
 ..."
    (file "./t4" line 7)

私が間違っているところにポインターはありますか?

4

3 に答える 3

1

正規表現が一致しなかったため、変数が割り当てられませんでした。の結果をチェックしてregexp、一致が成功したかどうかを確認する必要があります。-allのオプションを使用しない場合はregexp、ブール値のように扱うことができます。これを試して:

foreach line [split $output \n] {
    if {[regexp {<li><p>Your IP Address Is:.*?(\d+\.\d+\.\d+\.\d+)(?!\d)} $line -> ip]} {
        puts $ip
    }
}

これ->は実際には(奇妙な!)変数名であり、一致した文字列全体を保持します。私たちはそれに興味がないので(括弧の部分だけ)、アルファベット以外の部分を使用して、「これはそこに行きます」(ip変数へのサブマッチ)とニーモニックに言います。

于 2012-11-15T01:51:22.573 に答える
1

行に「address」(小文字)が含まれていますが、「Address」(大文字)と一致させようとしています。
-nocaseregexpコマンドにオプションを追加します。また、Tcl正規表現に貪欲性を混在させることはできません。最初の数量詞は、式全体が貪欲であるか非貪欲であるかを判断します(これが現在どこに文書化されているかはわかりません)。

regexp -nocase {IP Address.*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})} $line -> ip
于 2012-11-15T02:33:31.810 に答える
0

最終的な目標がホストの外部IPを取得することである場合は、exip.orgのようなAPIソリューションを使用します。

#!/usr/bin/env tclsh

set api http://api-nyc01.exip.org/?call=ip
if {[catch {exec curl --silent $api} output]} {
    puts "Failed to acquire external IP"
} else {
    puts "My external IP is $output"
}

特に米国外にお住まいの場合は、 APIサイトにアクセスして詳細を確認してください。このソリューションにはcurlが必要ですが、これをインストールする必要がある場合があります。

于 2012-11-15T15:01:07.113 に答える