none
あるページの最後のstringを検索する RRS feed

  • 質問

  • 今晩は。

    あるurlのあるページにアクセスし、ダウンロードします。

    そのhtmlを検索し最後の  <b><u>ABCDEF</u>:<br /> を検索したいたいのです。
    <b><u>ABCDEF</u>:<br />はそのページに何回か出現します。

    検索できたらその次の行をstringに代入します。


    "最後の"をどうやるかわかりません。

    もしPowerShellで、そのページをreverseできるのなら、最初の 
    <b><u>ABCDEF</u>:<br /> が目的のものになるのですが。

    なにかよい方法はないでしょうか?

    ちなみにvbscriptではこのようにできるそうです。

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    myFile = "C:\testfile"
    strPattern = "pattern_to_find"
    Set objFile = objFSO.OpenTextFile(myFile,1)
    Do Until objFile.AtEndOfStream
    numLine = objFile.Line
    strLine = objFile.ReadLine
    If InStr(1,"dir",strLine) > 0 Then
    finalNum = numLine
    End If
    Loop
    WScript.Echo "final line that pattern is found at: " , finalNum


    usage: cscript /nologo myscript.vbs



    pjo


    2008年2月3日 11:43

回答

すべての返信

  • 参考程度に聞いてください

     

    まず Select-Stringコマンドレットで、検索したい文字列をすべて洗い出し、変数に代入します。

    $a = Select-String -path test.htm -pattern "<b><u>ABCDEF</u>:<br />"

     

    結果として$aはオブジェクト型の配列変数となり、配列の最後が、pjo22さんの求めているデータがある場所となります。

    つまり

    $a[$a.Length -1]

    です。

     

    ただ、$a[$a.Length -1] は

    対象ファイル名:見つかった行番号:検索文字列

    というフォーマットで格納されているので、行番号を取り出すにはステップを踏む必要があります。

     

    まず文字列型にします

    $a[$a.Length -1].ToString()

     

    つぎに ":"  で文字列を分解

    $a[$a.Length -1].ToString().Split(":")

     

    さいごに、要素番号2のデータを取得することで、目的の行番号が取得できます。

    $a[$a.Length -1].ToString().Split(":")[2]

     

    要素番号は 1 であるべきはずなのに、なぜ2としたかというと

    対象ファイル名:見つかった行番号:検索文字列

     

    対象ファイル名にドライブ文字(C:\Workなど)が含まれているからです。

     

    このやり方が、すべてに通用するとは思っておりません。

    参考になればと思い、書いただけなので、使えない場合はスルーしてください。

     

     

     

     


    HIRO's.NET http://hiro.wankuma.com/

    HIRO's.NET Blog http://blogs.wankuma.com/hiro/

    2008年2月3日 13:23
  • HIRO's.NETさん

    早速のコメントありがとうございます。

    たいへん参考になりました。

    pjo
    2008年2月3日 13:27
  • こんばんは。
    この方法に関していくつか新しい質問が出てきました。

    $a = Select-String -path test.htm -pattern "<b><u>ABCDEF</u>:<br />"

    これを実行すると $aが、配列でないような気がするのですが。
    test.htmには複数のABCDEFがあり

    $a[$a.Length -1].ToString().Split(":")[2]

    これを実行すると オブジェクトにインデックスをつけることはできない というエラーが発生します。

    pjo
    2008年2月16日 12:20
  • このテストを実行したとき、たまたまABCDEFが1回しか登場しなかったので配列にならなかったようですので、直前ポストの質問は取り消します。

    さて、
    最後のABCDEFが見つかったら、その次の行の文字列をある変数に取り込みたいのですが、どうもよく方法がわかりません。
    その文字列は必ず"1."で始まっています。
    どうやったらよいかご教授ください。
    2008年2月16日 13:23
  • ちょっと安易な方法かもしれませんが、参考程度に...

     

    まず、htmlファイルを変数に読み込みます

     

    $file = [string](Get-Content hoge.htm)

     

    つぎに、$fileを改行コードで分割し、変数に入れます。

     

    $lines = $file.Split("\r\n")

     

    これで、hoge.htm の各行を $linesの配列変数に代入したことになります。

     

    あとは行番号がわかっているので

    "1."で始まるポジションを探して

    $startpos = $lines[行番号 - 1].IndexOf("1.")

     

    その位置から文字列を抜き出してはどうでしょうか?

     

    $data = $lines[行番号 -1].Substring($startpos)

     


    HIRO's.NET http://hiro.wankuma.com/

    HIRO's.NET Blog http://blogs.wankuma.com/hiro/

     

    2008年2月16日 14:29
  • HIRO's.NETさん

    どうもありがとうございます。
    各行を配列要素に代入する方法がわかりました。
    さっそくやってみます。

    pjo
    2008年2月16日 23:06
  • 試してみました。

    test.htmlにはロードしたページのhtml sourceがはいっています。

    $source = $ie.Document.documentElement.innerHTML
    Out-File -InputObject $source -FilePath d:\work\test.html

    $a = Select-String -Path d:\work\test.html -pattern "ABCDEF"
    $c =  $a[$a.Length -1].ToString().Split(":")[2]
    $file = [string](Get-Content -Path "d:\work\test.html")
    Out-File -InputObject $file -FilePath d:\work\file.txt
    $lines = $file.Split("\r\n")
    Out-File -InputObject $lines -FilePath d:\work\lines.txt
    # search the line which starts with 1.
    $startpos = $lines[$c - 1].IndexOf("1.")
    # extract the string from $startpos
    $data = $lines[$c -1].Substring($startpos)

    $startposには -1 が入っています。

    これを実行すると
    "1"個の引数を指定して "Susbstring"を呼び出し中に例外が発生しました: "StartIndex の値を 0 より小さくすることはできません。
    パラメータ名: startIndex
    というエラーがでます。

    lines.txtを見るとhtmlの各行が、一部文字が削除され途中で改行されています。
    たとえば
    <HEAD><TITLE>Weekly Wi

    e
    s - Page 21 - Fo
    ex T
    adi
    g</TITLE><BASE h
    ef=http://www.fo
    ex-tsd.com/> <META http-equiv=Co
    te
    t-Type co
    te

    test.htmlをここに貼り付けるには巨大すごると思うので、もし見ていただけるならどこかにuploadします。

    pjo
    2008年2月17日 0:12
  • $startpos が -1 となっているということですが、これは文字列が検索できなかったため

    ヒットしなかった)ということを意味しています。

    IndexOfメソッドについては、http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpref/html/frlrfSystemStringClassIndexOfTopic4.asp を参照してみてください。

    PowerShellのものではありませんが、説明は共通ですので一読されることをおすすめします。

     

    実際には、文字列を検索して見つかった場合に処理をするように書く必要があるでしょう。

    これには if を使用し

    if ( $startpos -gt -1 )

    {

     

    }

     

    のようにすべきかと思います。

    ifについては、私のサイトの http://hiro.wankuma.com/PowerShell/control/control01.htm を

    if中で使用している比較演算子については、http://hiro.wankuma.com/PowerShell/operator/operator04.htm を参照ください。

     

     

    >>lines.txtを見るとhtmlの各行が、一部文字が削除され途中で改行されています。

    というのが気になりますね。

    なぜ、そうなってしまったのでしょう?

     

    >>test.htmlをここに貼り付けるには巨大すごると思うので、もし見ていただけるならどこかにuploadします。

    見るのはかまいませんが、回答できるかどうかはわかりませんのであしからず。

     

    余談ですが、そのほかのスレッドで解決済みのものは[回答済み]ボタンをクリックしてスレッドを締めておいてください。

     


    HIRO's.NET http://hiro.wankuma.com/

    HIRO's.NET Blog http://blogs.wankuma.com/hiro/

    2008年2月17日 0:44
  • どうもこれはtest.htmlの行がきたいしているようになっていないような気がするのですが。

    お手数ですがtest.htmlを見てみてください。
    http://rapidshare.com/files/92489521/test.html

    実際に検索しているstringは<U>EURUSD</U> です。

    pjo
    2008年2月17日 1:41
  • test.html を見てみましたが、このファイルおかしくないでしょうか?

    なぜかすべて、1文字ごとに空白が挿入されているのが気になります。

     

    たとえば <head> タグも < H E A D > となっていますし、改行コードもおかしいですね。

    このファイル自体がhtmlファイルとして機能しないですよね?


    HIRO's.NET http://hiro.wankuma.com/

    HIRO's.NET Blog http://blogs.wankuma.com/hiro/

     

    2008年2月17日 3:06
  • どうもです。
    こちらでsourceを表示すると
    H T M L (空白が入る)にはなっておらず、 Firefoxで正常に表示できます。
    uploadでおかしくなったのでしょうか?


    2008年2月17日 4:00
  • html source を保存した後に、
    テキスト本文だけ抜き出せばよいような気がしますが、
    方法がわかりません。
    2008年2月17日 6:12
  •  

    http://www.jafsoft.com/doco/detagger_running_the_software.html#console_version

     

    これのconsole versionでhtml のdetaggingはできますね。

    2008年2月17日 7:15
  •  pjo22 さんからの引用
    どうもです。
    こちらでsourceを表示すると
    H T M L (空白が入る)にはなっておらず、 Firefoxで正常に表示できます。
    uploadでおかしくなったのでしょうか?


     

    私の環境もFirefoxです。

    一度、UPしたファイルを、ご自分でダウンロードして確認してもらえませんか?


    HIRO's.NET http://hiro.wankuma.com/

    HIRO's.NET Blog http://blogs.wankuma.com/hiro/

    2008年2月17日 12:24
  • はい。

    いまやって見ましたが、uploadしたものと同じですね。

    html sourceにも空白は入っていません。

     

    別のサイトにuploadしますので少々お待ちを。

     

    2008年2月17日 14:32
  •  

    どうも使いやすい

    file upload serviceがみつからないのですが、

    どこかありますか?

    2008年2月17日 14:55
  • 今日PCを変えて、再度 test.html をダウンロードしてみたら正常でした。
    当方の環境の問題かと思われます。申し訳ありません。

    以前
     HIROs-NET さんからの引用

    ちょっと安易な方法かもしれませんが、参考程度に...

     

    まず、htmlファイルを変数に読み込みます

     

    $file = [string](Get-Content hoge.htm)

     

    つぎに、$fileを改行コードで分割し、変数に入れます。

     

    $lines = $file.Split("\r\n")

     

    これで、hoge.htm の各行を $linesの配列変数に代入したことになります。

     

    あとは行番号がわかっているので

    "1."で始まるポジションを探して

    $startpos = $lines[行番号 - 1].IndexOf("1.")

     

    その位置から文字列を抜き出してはどうでしょうか?

     

    $data = $lines[行番号 -1].Substring($startpos)



    と回答したのですが、Get-Contentコマンドレットの使用方法を間違えていました。
    Get-Contentコマンドレットでファイルを読み込むと、行数分の配列ができます。
    今回の場合はtest.html は613行なので、要素数613のObject配列ができます。

    よって下記のようにしてみてください。

    $lines = Get-Content test.htm
    $startpos = $lines[行番号 - 1].ToSting().IndexOf("1.")
    $data = $lines[行番号 -1].Substring($startpos)
    2008年2月17日 23:54
  • HIROs-NETさん

    どうもです。

     

    test.htmlが正常にdownloadできて安心しました。

    早速試してみます。その結果をご報告します。

     

    pjo

     

    2008年2月18日 0:01
  • $a = Select-String -Path d:\work\test.html -pattern "EURUSD"
    $c =  $a[$a.Length -1].ToString().Split(":")[2]

    $lines = Get-Content -Path d:\work\test.html
    $startpos = $lines[$c - 1].ToString().IndexOf("1.")
    $data = $lines[$c -1].Substring($startpos)

    こうやったのですが何かおかしいような気がするのですが。

    「StartIndexの値を0より小さくできません」

    これから出かけて夕方戻ります。
    pjo
    2008年2月18日 0:36
  • 前にも説明したと思うのですが、IndexOfメソッドを使用して -1が返ってきた場合は、文字(列)を検索できなかったということになります。(この場合は"1."です)
    よって$startposには-1がセットされており、「StartIndexの値を0より小さくできません」が表示されているということになります。

    なので
    if ( $startpos -gt -1 )
    {
    $data = $lines[$c -1].Substring($startpos)
    }

    とする必要があります。

     


    HIRO's.NET http://hiro.wankuma.com/

    HIRO's.NET Blog http://blogs.wankuma.com/hiro/


    2008年2月18日 1:44
  • おかげさまで探している最後のstringをみつけることができるようになりましたが

     

    $dataは、1.xxxxx 以下長いstringが入っていますので、

    1.xxxxxxだけを抜き出す処理を書いています。

    2008年2月18日 12:12