like演算子について

解決


ぽっぽ  2009-02-10 23:45:28  No: 141498

Microsoft Visual Studio .NET 2003
.Net Framework 1.1
vb.net

度々すみません。
OracleデータからSqlserverにデータを渡すにあたり、
途中Oracleデータから構造体に格納時に禁則文字のチェックをします。
そこで関数を作成しましたが、下記の記述で
【astrSql】の中身が『[(株)リ-a]』の場合、
>実行時例外がスローされました : System.Exception - パターン文字列が有効ではありません。
のエラーがでてしまいました。
=============================================
        If "\" Like "[" & astrSql & "]" Then
            astrSql = Replace(astrSql, "\", "¥")
        End If
=============================================
どなか、教えていただけないでしょうか?


魔界の仮面弁士  2009-02-11 01:14:09  No: 141499

> If "\" Like "[" & astrSql & "]" Then
>     astrSql = Replace(astrSql, "\", "¥")
> End If

これは、astrSql が『\』1 文字の時にしか True にならないので、
  If astrSql = "\" Then
    astrSql = "¥"
  End If
と同義になってしまいますが、それで良いのでしょうか?

>【astrSql】の中身が『[(株)リ-a]』の場合、
つまり、
  Dim astrSql As String = "[(株)リ-a]"
  If "\" Like "[" & astrSql & "]" Then
    astrSql = Replace(astrSql, "\", "¥")
  End If
という事ですね。パターン文字列が『[[(株)リ-a]]』になっています。

> System.Exception - パターン文字列が有効ではありません。
もし、『[(株)リ-a]』という指定が、
  『[』または『(』または『株』または『)』または『リ』または『-』または『a』または『]』
を意図しているのだとしたら、
  If target Like "[[(株)リ-a]]" Then
ではなく、
  If (target Like "[[-(株)リa]") Or (target Like "]") Then
などと処理する必要があるでしょう。

より複雑な検索が必要な場合には、正規表現(RegExp オブジェクト)による
検索を行うことも検討してみてください。


ぽっぽ  2009-02-11 01:54:49  No: 141500

>> If "\" Like "[" & astrSql & "]" Then
>>     astrSql = Replace(astrSql, "\", "¥")
>> End If
>
>これは、astrSql が『\』1 文字の時にしか True にならないので、
>  If astrSql = "\" Then
>    astrSql = "¥"
>  End If
>と同義になってしまいますが、それで良いのでしょうか?
はい。
"\"半角のみ検索です。

>>【astrSql】の中身が『[(株)リ-a]』の場合、
>つまり、
>  Dim astrSql As String = "[(株)リ-a]"
>  If "\" Like "[" & astrSql & "]" Then
>    astrSql = Replace(astrSql, "\", "¥")
>  End If
>という事ですね。パターン文字列が『[[(株)リ-a]]』になっています。
すみません。文章に誤りがありました。
>【astrSql】の中身が『[(株)リ-a]』の場合、
ではなく
【astrSql】の中身は『(株)リ-a』です。
あいまい検索をするにあたり変数の前後に"["と"]"を使用しました。

>> System.Exception - パターン文字列が有効ではありません。
>もし、『[(株)リ-a]』という指定が、
>  『[』または『(』または『株』または『)』または『リ』または『-』または『a』または『]』
>を意図しているのだとしたら、
>  If target Like "[[(株)リ-a]]" Then
>ではなく、
>  If (target Like "[[-(株)リa]") Or (target Like "]") Then
>などと処理する必要があるでしょう。
【astrSql】の中身が[(株)リ-]までであればエラーは出ませんでした。
しかし、『-』後に文字が入るとエラーが発生してしまうようです。
like演算子を使用する際、
検索で『?』『*』『#』『!』『-』を判断する為、エラーが発生していたと思います。

>より複雑な検索が必要な場合には、正規表現(RegExp オブジェクト)による
>検索を行うことも検討してみてください。

RegExpをしらべてみたのですが、VB.netのつくりが良くわかりませんでした。
もう少し調べてみます。


魔界の仮面弁士  2009-02-11 02:22:50  No: 141501

> "\"半角のみ検索です。

であれば、
  Dim astrSql As String = "(株)リ-a"
  If astrSql.Contains("\") Then
で良いかと。あるいは、
  If astrSql.IndexOf("\") >= 0 Then
とか。

> 【astrSql】の中身は『(株)リ-a』です。
> しかし、『-』後に文字が入るとエラーが発生してしまうようです。
"a" < "リ" の関係にあるからです。

『-』を一つの文字としてみたいなら、先に書いたように、
- を [ ]内の先頭に記述する必要があります。

『-』を「範囲」の意味にしたいなら、リとaを入れ替えねばなりません。
『a-リ』すなわち「"a"以上"リ"以下」という範囲は OK ですが、
『リ-a』すなわち「"リ"以上"a"以下」という範囲は NG です。
また、『a-』の場合は、「"a"以上のすべての文字」を意味します。

> RegExpをしらべてみたのですが、VB.netのつくりが良くわかりませんでした。
すみません。Regex の誤記です。

  'Imports System.Text.RegularExpressions
  Dim re As New Regex("[(株)リ\-a]")
  If re.IsMatch( "\" ) Then


ぽっぽ  2009-02-11 04:25:24  No: 141502

Dim re As Regex
re = New Regex("[" & astrSql & "]")
If re.IsMatch("\") Then
    astrSql = Replace(astrSql, "\", "¥")
End If

でためしてみたのですが・・・。
うまくいきませんでした。
Regexの中の文字列は変数では渡せないのでしょうか??


魔界の仮面弁士  2009-02-11 05:30:14  No: 141503

> Regexの中の文字列は変数では渡せないのでしょうか??
渡せます。そもそもクラス側にとってみれば、渡された引数が
変数であったかどうかを知る術はありませんし。

> うまくいきませんでした。
例外が出るのであれば、その例外メッセージと、そのときの
astrSql の内容を正確に記述してください。
(特に、特殊文字の指定が考慮されているかを確認してみてください)

> astrSql = Replace(astrSql, "\", "¥")

こちらから、下記の 2点を確認させてください。

(1) 『(株)リ-a』という検索パターンの意図が不明瞭です。
  その検索パターンに「一致する文字列」と「一致しない文字列」を、
  それぞれ数個ずつ、具体例として挙げてもらえないでしょうか。

  DB 変換のための「禁則文字」を探しているとのお話でしたが、
  少なくとも "\" とは絶対に一致しないはずなので、何のために
  この作業を行っているのか、それを確認したいのです。

(2) ぽっぽさんが書かれたコードは、Like版も Regex版も
      「\」一文字が、astrSql で指定された曖昧検索パターンに
      一致するかどうかを検証し、一致すれば、その検索パターン中の
      半角「\」を、すべて全角「¥」に置換。
  になっていますが、それは本当にやりたい事なのでしょうか?

  本当は、「検索する側」と「検索される側」が逆で、
      astrSql の中に、「\」が含まれているのかどうかをチェックし、
      「\」が含まれていれば、それを全角「¥」に置換する。
  という処理を求めていたりはしませんか?


ぽっぽ  2009-02-11 06:14:23  No: 141504

>(1) 『(株)リ-a』という検索パターンの意図が不明瞭です。
>  その検索パターンに「一致する文字列」と「一致しない文字列」を、
>  それぞれ数個ずつ、具体例として挙げてもらえないでしょうか。
>
>  DB 変換のための「禁則文字」を探しているとのお話でしたが、
>  少なくとも "\" とは絶対に一致しないはずなので、何のために
>  この作業を行っているのか、それを確認したいのです。

すみません。
情報不足でした。
コマンドウィンドウ-イミディエイトで確認したところこのように出ました。
=============================================================================================
【¥が変数に入っている場合・・・エラー】
?astrSql
"(株)ああ\"
?New Regex("[" & astrSql & "]")
実行時例外がスローされました : System.ArgumentException - 解析中 "[(株)ああ\]" - 未終了の [] セットです。
パラメータ名 : [(株)ああ\]

【変数に対象のものが無い場合・・・正常】
?astrSql
"株式会社ああああ"
?New Regex("[" & astrSql & "]")
{System.Text.RegularExpressions.Regex}
    Options: None
    RightToLeft: False

【変数に対象のものが無い場合・・・エラー】
?astrSql
"(株)リ-a"
?New Regex("[" & astrSql & "]")
式またはステートメントの評価が中止されました。
=============================================================================================

>(2) ぽっぽさんが書かれたコードは、Like版も Regex版も
>      「\」一文字が、astrSql で指定された曖昧検索パターンに
>      一致するかどうかを検証し、一致すれば、その検索パターン中の
>      半角「\」を、すべて全角「¥」に置換。
>  になっていますが、それは本当にやりたい事なのでしょうか?
>
>  本当は、「検索する側」と「検索される側」が逆で、
>      astrSql の中に、「\」が含まれているのかどうかをチェックし、
>      「\」が含まれていれば、それを全角「¥」に置換する。
>  という処理を求めていたりはしませんか?

ほんとうにすみません。私の表現がおかしかったです。
>      astrSql の中に、「\」が含まれているのかどうかをチェックし、
>      「\」が含まれていれば、それを全角「¥」に置換する。
この処理を求めていました。


YuO  2009-02-11 07:40:05  No: 141505

Regexクラスにおいて,\は意味を持つ文字です。
\を置き換えたい場合,Regexのパターンとしては\\を渡さなければなりません。
http://msdn.microsoft.com/ja-jp/library/4edbef7e.aspx
http://msdn.microsoft.com/ja-jp/library/system.text.regularexpressions.regex.escape(VS.71).aspx

で,パターンの一部が外部から渡されるのであれば,Escapeメソッドを使うことを考えてみるのも良いでしょう。
http://msdn.microsoft.com/ja-jp/library/system.text.regularexpressions.regex.escape.aspx
http://msdn.microsoft.com/ja-jp/library/system.text.regularexpressions.regex.escape(VS.71).aspx

で,
>      astrSql の中に、「\」が含まれているのかどうかをチェックし、
>      「\」が含まれていれば、それを全角「¥」に置換する。
だけであれば,
astrSql = astrSql.Replace("\"c, "¥"c)
とかになると思います。


魔界の仮面弁士  2009-02-11 23:59:09  No: 141506

> この処理を求めていました。
やはり。

であれば検索無しで、いきなり Replace するだけで充分でしょうね。
ぽっぽさんが最初に書かれていた
  astrSql = Replace(astrSql, "\", "¥")
の行だけで良いかと思います。

なお、YuO さんが書かれたように String.Replace を使う方法もありますが、
この方法だと、astrSql が Nothing の時には使えなくなってしまいますので、
置換処理自体は、ぽっぽさんの初案そのままの方が安全かと思います。


ぽっぽ  2009-02-13 01:07:23  No: 141507

YuOさん、魔界の仮面弁士さん度々ありがとうございます。

>astrSql = Replace(astrSql, "\", "¥")
で、処理を行うことにしました。
Null値が入った場合もエラーが帰ってしまっていた為、
その際は変換処理を行わないようにしました。

Regexクラスについては、こういったものがあることを知らなかった為、
今後使用する機会があれば活用していきたいと思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加