• ベストアンサー

「?」の入った文字列置換を、RegEx.Replaceで行いたい

WSHを使い、あるhtmファイルの中にある特定の文字列を、RegEx.Replaceを使って置換しようとしています。通常の文字列置換についてはなんとか成功しているのですが、下記のケースで壁に当たっています。前に進める為にはどうしたらよいか、ヒントをご存知の方がいれば大変有り難く思います。 今回作業の特徴としては 1)置換前の文字列の中にメタキャラ「?」が含まれており、 2)置換前の文字列は、DBから読み込んできた文字列である の2点です。(ちなみに1だけでは成功しているのですが、1と2が組み合わさると上手くいきません) 具体的には、下記のサンプルで置換前の文字列を url_before = "test.asp\?param=999" (?についてはエスケープ文字付与) のように明示的に書いてやると置換に成功しました。ところがDBから取得してきた文字列で置換をしようとしても失敗となります。 たとえばrs.fields("item")の中身が"test.asp?param=999"だったとして、先ほどの箇所を url_before = replace(rs.fields("item"), "?", "\?") とすると、置換されないのです。 '----- サンプル ----- Set fso = CreateObject("Scripting.FileSystemObject") Set regEx = New RegExp Set inFile = fso.OpenTextFile("c:\hoge\test1.htm") Set outFile = fso.CreateTextFile("c:\hoge\test1_wk.htm") ◆動くケース:url_before = "test.asp\?param=999" ◆動かないケース:url_before = replace(rs.fields("item"), "?", "\?") url_after = "test_999.htm" regEx.pattern = url_before repStr = url_after Do Until inFile.AtEndOfStream tempLine = inFile.ReadLine repLine = regEx.Replace(tempLine, repStr) outFile.WriteLine repLine Loop inFile.Close outFile.Close

質問者が選んだベストアンサー

  • ベストアンサー
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.7

とりあえずテストコードを書いてみたけど、特に問題ないみたいです。 なのでやっぱり質問とか補足で書かれてないところで間違えてる可能性が高いかと。 コード: Function iif(c,t,f) If c Then iif = t Else iif = f End If End Function Set rs = WSCript.CreateObject( "ADODB.Recordset" ) rs.Open "T1", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb;" url_before = Replace( rs.Fields( "item" ).Value, "?", "\?" ) url_after = rs.Fields( "replacer" ).Value rs.Close url_before_OK = "test.asp\?param=999" WScript.Echo "1)", url_before, ":", iif( url_before = url_before_OK, "OK", "NG" ) Set re = new RegExp re.Pattern = url_before s1 = "/g/test.asp?param=999" a1 = "/g/test_999.htm" r1 = re.Replace( s1, url_after ) WScript.Echo "2)", s1, "->", r1, ":", iif( r1 = a1, "OK", "NG" ) データ db1.mdb テーブル T1の内容(左辺は列名): item=test.asp?param=999, replacer=test_999.htm 実行結果: 1) test.asp\?param=999 : OK 2) /g/test.asp?param=999 -> /g/test_999.htm : OK

その他の回答 (7)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.8

#6>"等しい"と出ます repLine=Replace(tempLine, "test.asp?param=999", "test_999.htm") または、 >◆動くケース:url_before = "test.asp\?param=999" で直接指定した場合は >repLine = regEx.Replace(tempLine, repStr) が機能するが rs.fields("item") を元にするものはうまく機能しないが "test.asp?param=999"とrs.fields("item")じたいは等しいと思われる 上記から考えられるのは、 >repLine = regEx.Replace(tempLine, repStr) の行までにrs.fields("item") (または元にした部分)が変質している ということですね。 データベースから取り出すタイミングと処理する時のタイミングがおかしいんじゃないですかね。 私も 質問とか補足で書かれてないところで間違えてる可能性が高い と思います。

kumar
質問者

補足

皆さん、親切なフォローありがとうございます。お陰様でなんとか変換することができるようになりました。深謝いたします。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.6

#5>結果は(T_T)です。 repLine=Replace(tempLine, "test.asp?param=999", "test_999.htm") は、とりあえずうまくいくんですよね? If rs.fields("item") = "test.asp?param=999" Then MsgBox "等しい" Else MsgBox "等しくない" End If を試してみたらどうなりますか?

kumar
質問者

補足

BLUEPIXYさん、いつもありがとうございます。 ご指摘の方法試してみましたところ、"等しい"と出ます。取り急ぎご連絡まで。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

#4補足> すいません、ずっと勘違いしていたようです。 なんていうか、こういうような場合には、 わざわざRegEx.Replace を使う必要はないように思います。 例えば url_before = "test.asp?param=999" url_after = "test_999.htm" repLine=Replace(tempLine, url_before, url_after) のようにすればいいだけのように思えます。 それはそれとして、 rs.fields("item") を用いたものが置換されないのは、 WScript.Echo で表示させて、見た目は一緒でも 一致しない何かが含まれているんじゃないでしょうか 一度ファイルにでも出力して、16進ダンプ表示でもしてみたらどうでしょうか?

kumar
質問者

補足

BLUEPIXYさん、いつもありがとうございます。 repLine=Replace(tempLine, url_before, url_after)でやってみました。 url_before = "test.asp?param=999"のケースとurl_before = "test.asp\?param=999"の両方のケースを試してみましたが、結果は(T_T)です。 おそらくBLUEPIXYさんが予測されている通り、見た目には同じでも別キャラクタなのかもしれません。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>そのような訳で変換する文字列は、一対一対応でねらいを定めてやるのが確実かと思います。 補足で言わんとされることが良く判りませんが、 回答側には、どのようなパターンがあって、どのようなことが求められいるのかはっきりとはわかりません。 望むようにされればいいと思います。

kumar
質問者

補足

BLUEPIXYさん、言葉足らずで大変失礼いたしました。 正確に書きます。 下記のいずれも、url_after = "test_999.htm"とします。 <ケース1> regEx.pattern = "test.asp\?param=999" repStr = url_after とすれば置換されて正常終了しました。ところが、 <ケース2> url_before = rs.fields("item") url_before = replace(url_before, "?", "\?") wscript.echo url_before <---(この時点でこの中身は「test.asp\?param=999」です) regEx.pattern = url_before repStr = url_after のように、DBからレコードセットとして取ってきた値を入れると、置換されなくて困っております。 実際にはDBから取得したURL名をそれぞれ別の名前に自動で置き換えしたいと計画しておりますため、ケース2のやり方で前に進められるのが望ましいという背景があります。 なおBLUEPIXYさんがサジェストして下さった方法も大変興味深いのですが、実際にやってみますと、対象ページの中で置換しなくても良い箇所まで置換されてしまった(regEx.pattern = "\..*="ですから、同じ表現の箇所は全て対象になってしまいますね)次第で、今回は上手くいかなかったのです。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.3

> url_before = replace(rs.fields("item"), "?", "??") 直後に、url_beforeをWScript.Echoで出力させてみては。 あと期待する値と比較してみるとか。 もしかして、Fieldオブジェクトの既定プロパティが違ってるとか、予期せぬ形式に文字列書式化されてるかも。 すでにそれくらいのデバッグはやられてるかもしれませんが。

kumar
質問者

補足

ありがとうございます。おっしゃる通りで、予期せぬ形式に文字列が置き換わっているかもしれないので、wscript.echoさせてみました。 url_before = replace(rs.fields("item"), "?", "??") の場合は置換対象文字列が test.asp??param=999 となっていました。これを実行させたのですが、置換されていませんでした。 次に url_before = replace(rs.fields("item"), "?", "\?") とした場合は、wscript.echoすると test.asp\?param=999 と出てきますが、こちらでやってもダメです。 明示的に url_before = "test.asp\?param=999" とすれば文字列置換されるのに、どうしてなのか頭を悩ませております。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>test.asp?param=999→test_999.htm >と一括置換することです。 そういうこともあるかな・・とはちょっと思いましたが… またはずしてたらすみません ---------------------------------------------------------------- 'test.asp?param=999→test_999.htm Set regEx = New RegExp url_before = "test.asp?param=999" regEx.pattern = "\..*=" '(1)ピリオドから=までを無条件にアンダーバーに置き換える url_after = regEx.replace(url_before,"_") & ".htm" WScript.Echo url_after '(2)ファイル名と数字をマッチさせて取り出す regEx.pattern ="(^.*?)\.asp\?param=(\d+)" Set Matches = regEx.Execute(url_before) fileName = Matches(0).SubMatches(0) No = Matches(0).SubMatches(1) url_after = fileName & "_" & No & ".htm" WScript.Echo url_after

kumar
質問者

補足

情報ありがとうございます。特に(1)の方法があるのですね。とても参考になります。 小さなページであればこの方法で前に進めると思います。 ただこの方法ではページの中に他のリンクがあると、それも一緒に変換されてしまうことになります。 そのような訳で変換する文字列は、一対一対応でねらいを定めてやるのが確実かと思います。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

test.asp?param=999→test.asp\?param=999 という処理ということでよろしいでしょうか? Set regEx = New RegExp url_before = "test.asp?param=999" regEx.pattern = "\?" url_after = regEx.replace(url_before,"\?") WScript.Echo url_after というような感じになります。

kumar
質問者

補足

BLUEPIXYさん、早速のメッセージありがとうございます。 >test.asp?param=999→test.asp\?param=999という処理ということでよろしいでしょうか? 残念ながらそうではありません。今回の目標は、 test.asp?param=999→test_999.htm と一括置換することです。 さらに置換候補となる文字列をDBから取ってきて処理を回しますから、url_beforeにはレコードセットに取ってきた値となります。 取り急ぎですが、説明補足させていただきます。

関連するQ&A