こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

「?」の入った文字列置換を、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

投稿日時 - 2006-03-09 12:37:44

QNo.2017305

すぐに回答ほしいです

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

とりあえずテストコードを書いてみたけど、特に問題ないみたいです。
なのでやっぱり質問とか補足で書かれてないところで間違えてる可能性が高いかと。

コード:
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

投稿日時 - 2006-03-11 11:38:06

ANo.7

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.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") (または元にした部分)が変質している
ということですね。
データベースから取り出すタイミングと処理する時のタイミングがおかしいんじゃないですかね。
私も
質問とか補足で書かれてないところで間違えてる可能性が高い
と思います。

投稿日時 - 2006-03-11 12:24:21

補足

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

投稿日時 - 2006-03-21 10:12:19

ANo.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
を試してみたらどうなりますか?

投稿日時 - 2006-03-11 02:20:53

補足

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

投稿日時 - 2006-03-11 09:35:31

ANo.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進ダンプ表示でもしてみたらどうでしょうか?

投稿日時 - 2006-03-10 20:19:08

補足

BLUEPIXYさん、いつもありがとうございます。
repLine=Replace(tempLine, url_before, url_after)でやってみました。
url_before = "test.asp?param=999"のケースとurl_before = "test.asp\?param=999"の両方のケースを試してみましたが、結果は(T_T)です。

おそらくBLUEPIXYさんが予測されている通り、見た目には同じでも別キャラクタなのかもしれません。

投稿日時 - 2006-03-10 21:11:43

ANo.4

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

投稿日時 - 2006-03-10 13:07:11

補足

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 = "\..*="ですから、同じ表現の箇所は全て対象になってしまいますね)次第で、今回は上手くいかなかったのです。

投稿日時 - 2006-03-10 18:44:11

ANo.3

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

すでにそれくらいのデバッグはやられてるかもしれませんが。

投稿日時 - 2006-03-10 00:55:46

補足

ありがとうございます。おっしゃる通りで、予期せぬ形式に文字列が置き換わっているかもしれないので、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"
とすれば文字列置換されるのに、どうしてなのか頭を悩ませております。

投稿日時 - 2006-03-10 17:46:49

ANo.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

投稿日時 - 2006-03-09 19:31:17

補足

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

そのような訳で変換する文字列は、一対一対応でねらいを定めてやるのが確実かと思います。

投稿日時 - 2006-03-10 12:36:25

ANo.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
というような感じになります。

投稿日時 - 2006-03-09 12:55:29

補足

BLUEPIXYさん、早速のメッセージありがとうございます。

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

投稿日時 - 2006-03-09 17:38:54

あなたにオススメの質問