VB6.0にて開発
テキストBOX1に「あいうえお(テスト)かきくけこ」と入力し
ボタンをクリックするとテキストBOX2には「あいうえおかきくけこ」と表示させたい時、Replaceで()内を削除させることはできるのでしょうか?
また違う方法があるのでしたら、是非おしえてください。。よろしくお願いいたします。
Instr関数,Mid関数を使えばできるかとおもいます。
#Replace関数じゃ不特定の文字列は変換出来ないような気がします。
ちゃんと調べてませんが・・・|o_o;
KGさん、ありがとうございます。
cnt1 = InStr(strNameSP, "(")
cnt2 = InStr(strNameSP, ")")
cnt3 = cnt2 - cnt1
strNameSP = Replace(strNameSP, Mid(strNameSP, cnt1, cnt3 + 1), "")
こんな感じにすると何とか()内は削除できました。
大変申し訳ないのですが、()がテキストに何個もあるときや
()がとじられてなく"("だけの時のエラー表示などをしたいのです。
何か良い方法はありませんでしょうか?
過去ログのどこかに、
含まれている文字が何個存在するか、
カウントするサンプルコードが合ったので、
流用してみましょう!
> Replaceで()内を削除させることはできるのでしょうか?
とりあえず、提示された条件だけを見るならば、
With CreateObject("VBScript.RegExp")
.Pattern = "(.*?)"
.Global = True
Text2.Text = .Replace(Text1.Text, "")
End With
で良いような気もしますが、質問文からは、細かい仕様を
読み取れなかったので、適切な回答になっているかは分かりません。
たとえば、
1. 提示されているのは全角の括弧ですが、半角の括弧はどうするのか?
2. 括弧が複数回存在した場合の対応は? たとえば、『あ(い)う(え)お』に対しては、
「あお」になるべきなのか、それとも「あうお」になるべきなのか。
3. 始まりの括弧と終わりの括弧の数が一致していなかった場合は?
とか……。それによって、コーディング等も変わってくるかと。
Replaceを正規表現のReplaceと
勝手に判断しまして・・
Text = "あいうえお(テスト)かきくけこ"
Regex.Pattern="\(\)"
Regex.Replace(Text, "")
Regex.Pattern="\(*\)"の間違い
全角の()だったか・・
Regex.Pattern="\(.*\)"の間違い
いなさん、魔界の仮面弁士さん、ありがとうございます。
>1. 提示されているのは全角の括弧ですが、半角の括弧はどうするのか?
これについては、入力されたものを一度半角英数にしてますので大丈夫です。
>2. 括弧が複数回存在した場合の対応は? たとえば、『あ(い)う(え)お』に対しては、
あお」になるべきなのか、それとも「あうお」になるべきなのか。
「あ(い)う(え)お」の場合は「あうお」と表示させたいです。
>3. 始まりの括弧と終わりの括弧の数が一致していなかった場合は?
この場合はそのまま無視で構いません。
追加としては括弧内に括弧がある場合は大元の括弧からすべて削除というのもしたいのです。
説明が不足していると思われますが、ご指導よろしくお願いいたします。
Text = "あいうえお(テスト)かきくけこ"
で
Regex.Pattern="\([^\(]*\)"
Regex.Replace(Text, "")
を繰り返せばいいのかな?
あんさん、ありがとうございます。
Dim Regexp
Set Regexp = New Regexp
strNameSP = StrConv(strNameSP, vbNarrow)
strNameSP = Replace(strNameSP, " ", "")
Regexp.Pattern = "\(.*\)"
strNameSP = Regexp.Replace(strNameSP, "")
とやってみたのですが、ユーザー定義型は定義されてませんと表示されちゃいます。どうすれば良いのでしょうか?
()の中にさらに()があるというようなことがなければ
あんさんの案がシンプルで良いかと思います:D
アーリバインドしてないのであれば、魔界の仮面弁士さんが返信してらっしゃる
ようにCreateObjectを使ってやらないといけませんね。
>Set Regexp = New Regexp
を
Set Regexp = CreateObject("VBScript.RegExp")
です。
>Regexp.Pattern = "\(.*\)"
これではなくて
Regexp.Pattern = "\([^\(]*\)"
()が無くなるまで置換は繰り返します。
#既に気づいて検証してらっしゃるかもしれませんが|^-^;
あんさん、KGさん、ありがとうございます!
無事に括弧内クリアができました^▽^v
Regexpを調べたら結構役に立つクラスなんですねー
勉強になります。。
今後ともお世話になると思いますが、よろしくお願いいたします。
ほんと、助かりました。ありがとうございました。
Set Reg = CreateObject("VBScript.RegExp")
Reg.Pattern = "\([^\(\)]*\)"
Do
Text2 = Reg.Replace(Text,"")
If len(Text2) = Len(Text) Then Exit Do
Text = Text2
Loop
これで動作確認できました。
>とやってみたのですが、ユーザー定義型は定義されてませんと表示されちゃいます。どうすれば良いのでしょうか?
Set Regexp = New Regexp
を
Set Reg CreateObject("VBScript.RegExp")
にしてみてください
>Regexp.Pattern = "\([^\(]*\)"
これはちょっとあまかったです。
"abc(def(ghi)ikl(mno)pqr)stu"
が救えなかったです。
整理してみました。
Text = "あいうえお(テスト)かきくけこ"
とか
Text = "abc(def(ghi)ikl(mno)pqr)stu"
で
Set Reg = CreateObject("VBScript.RegExp")
Reg.Pattern = "\([^\(\)]*\)"
Reg.Global = True
While Reg.Test(Text)
Text2 = Reg.Replace(Text,"")
Text = Text2
Wend
これでネストもOKかな
>()がとじられてなく"("だけの時のエラー表示などをしたいのです。
何か良い方法はありませんでしょうか?
置換した後
If Reg.Test(Text,"[\(\)]") Then
' エラー処理
End If
かな
あんさん、ありがとうございます。
大変わかりやすくまとめてくださって感謝です。
完璧なまでにマスターしましたよ^^
>If Reg.Test(Text,"[\(\)]") Then
>' エラー処理
>End If
Reg.Pattern = "[\(\)]"
If Reg.Test(Text) Then
' エラー処理
End If
の間違い今日は間違ってばかり・・
もしよろしかったらでいいのですが、
"\([^\(\)]*\)" の正規表現の意味合いを教えてください。
ネット検索しましたが、なかなか詳しい解説がないものですね。。
¥の意味合いは何ですか?
http://www.sixnine.net/regexp/index.html
ここなどいかがですか?
参考になります。
度々ありがとうございます。。
>¥の意味合いは何ですか?
()は正規表現では特別な意味合いをもちます。
グルーピングといいます。
()を使用した過去ログがあります。
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200507/05070075.txt
なので()をあらわしたい場合は\(\)と記述するのです。
蛇足までに。
Option Explicit
Private Sub Form_Load()
Text1.Text = "あ(い((う)え(お)か)きく)けこ(さし)す"
Text2.Text = "最も外側の括弧を除去"
Text3.Text = "最も内側の括弧を除去"
Text4.Text = "内側の括弧を繰り返し除去"
End Sub
Private Sub Command1_Click()
Dim S As String
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "\(.*\)"
Text2.Text = .Replace(Text1.Text, "")
.Pattern = "\([^\(]*?\)"
Text3.Text = .Replace(Text1.Text, "")
S = Text1.Text
Do
S = .Replace(S, "")
Loop Until S = .Replace(S, "")
Text4.Text = S
End With
End Sub
# うーむ。ループさせないと無理かな……。
今まで出ていないようなのでゴリゴリ版…
バグ潜んでいると思います。
debug.? DeleteOverBracket("ab(abc(123)def(456)ghi)cd((456))e")
Function DeleteOverBracket(ByVal s As String) As String
Dim i As Long '検索結果位置
Dim Bracket As Long 'その時点での括弧の階層数
Dim sta As Long '")"の直後の位置
i = 0
Bracket = 0
sta = 1 '0文字目に")"があると仮定する
Do
i = FindString(s, i + 1, "(", ")")
If i = 0 Then Exit Do
Select Case Mid$(s, i, 1)
Case "("
If Bracket = 0 Then
'一番上層の開き括弧"("の直前までコピー
DeleteOverBracket = DeleteOverBracket + Mid$(s, sta, i - sta)
End If
Bracket = Bracket + 1
Case ")"
Bracket = Bracket - 1
If Bracket = 0 Then
'全ての括弧が閉じたので位置を保存
sta = i + 1
End If
End Select
Loop
'尻尾を追加
DeleteOverBracket = DeleteOverBracket + Mid$(s, sta, Len(s) - sta + 1)
End Function
Function FindString(ByVal s As String, ByVal p As Long, ParamArray c() As Variant) As Long
Dim v As Variant
Dim i As Long
FindString = Len(s) + 1
For Each v In c
i = InStr(p, s, v)
If i <> 0 Then
If i < FindString Then
FindString = i
End If
End If
Next
If FindString = Len(s) + 1 Then FindString = 0
End Function
( ) の対応関係をチェックする場合、()のネストの数に上限を設けない限り、正規表現だけでチェックするのは本質的に不可能です。
(正規文法の範囲外の文法であり、、正規表現は正規文法に合致する文法しか記述できない)
C言語の掲示板なら「yacc とか bisonで自動生成させましょう」で終わりなんですが、自動生成したCのソースをVBに移植するのが大変そうなので、この程度のシンプルなルールなら自力でプログラムを書く方が早い思います。
なぜ正規表現で表現できないのにyaccやbisonで自動生成できるのかといった話は形式言語とかオートマトン、字句解析、構文解析等の勉強するとよくわかるのですが、説明すると長いので、参考資料だけあげておきます。
http://cl.it.okayama-u.ac.jp/kougi/h16/data/gengo2p.pdf
http://www.teu.ac.jp/kmdit/Lectures/Automaton/H16/H16A&LNo3.ppt
http://hwb.ecc.u-tokyo.ac.jp/current/CDD1B8ECBDB82FA5C1A5E7A5E0A5B9A5ADA1BCB3ACC1D8.html
魔界の仮面弁士さん、ガッさん、大変参考になりました。
今後ともよろしくお願いいたします。
ツイート | ![]() |