()内を置換し削除させるには?

解決


劇団しゃらら  2005-09-21 00:19:36  No: 125510

VB6.0にて開発
テキストBOX1に「あいうえお(テスト)かきくけこ」と入力し
ボタンをクリックするとテキストBOX2には「あいうえおかきくけこ」と表示させたい時、Replaceで()内を削除させることはできるのでしょうか?
また違う方法があるのでしたら、是非おしえてください。。よろしくお願いいたします。


KG  2005-09-21 00:31:55  No: 125511

Instr関数,Mid関数を使えばできるかとおもいます。

#Replace関数じゃ不特定の文字列は変換出来ないような気がします。
 ちゃんと調べてませんが・・・|o_o;


劇団しゃらら  2005-09-21 01:03:31  No: 125512

KGさん、ありがとうございます。

cnt1 = InStr(strNameSP, "(")
cnt2 = InStr(strNameSP, ")")
cnt3 = cnt2 - cnt1
strNameSP = Replace(strNameSP, Mid(strNameSP, cnt1, cnt3 + 1), "")

こんな感じにすると何とか()内は削除できました。
大変申し訳ないのですが、()がテキストに何個もあるときや
()がとじられてなく"("だけの時のエラー表示などをしたいのです。
何か良い方法はありませんでしょうか?


いな  2005-09-21 01:15:31  No: 125513

過去ログのどこかに、
含まれている文字が何個存在するか、
カウントするサンプルコードが合ったので、
流用してみましょう!


魔界の仮面弁士  2005-09-21 01:15:43  No: 125514

> Replaceで()内を削除させることはできるのでしょうか?

とりあえず、提示された条件だけを見るならば、
    With CreateObject("VBScript.RegExp")
        .Pattern = "(.*?)"
        .Global = True
        Text2.Text = .Replace(Text1.Text, "")
    End With
で良いような気もしますが、質問文からは、細かい仕様を
読み取れなかったので、適切な回答になっているかは分かりません。

たとえば、
  1. 提示されているのは全角の括弧ですが、半角の括弧はどうするのか?
  2. 括弧が複数回存在した場合の対応は? たとえば、『あ(い)う(え)お』に対しては、
  「あお」になるべきなのか、それとも「あうお」になるべきなのか。
  3. 始まりの括弧と終わりの括弧の数が一致していなかった場合は?
とか……。それによって、コーディング等も変わってくるかと。


あん  2005-09-21 01:27:02  No: 125515

Replaceを正規表現のReplaceと
勝手に判断しまして・・

Text = "あいうえお(テスト)かきくけこ"
Regex.Pattern="\(\)"
Regex.Replace(Text, "")


あん  2005-09-21 01:27:45  No: 125516

Regex.Pattern="\(*\)"の間違い


あん  2005-09-21 01:31:39  No: 125517

全角の()だったか・・


あん  2005-09-21 01:34:56  No: 125518

Regex.Pattern="\(.*\)"の間違い


劇団しゃらら  2005-09-21 01:36:08  No: 125519

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

>1. 提示されているのは全角の括弧ですが、半角の括弧はどうするのか?
これについては、入力されたものを一度半角英数にしてますので大丈夫です。

>2. 括弧が複数回存在した場合の対応は? たとえば、『あ(い)う(え)お』に対しては、
あお」になるべきなのか、それとも「あうお」になるべきなのか。
「あ(い)う(え)お」の場合は「あうお」と表示させたいです。

>3. 始まりの括弧と終わりの括弧の数が一致していなかった場合は?
この場合はそのまま無視で構いません。

追加としては括弧内に括弧がある場合は大元の括弧からすべて削除というのもしたいのです。

説明が不足していると思われますが、ご指導よろしくお願いいたします。


あん  2005-09-21 01:50:29  No: 125520

Text = "あいうえお(テスト)かきくけこ"

Regex.Pattern="\([^\(]*\)"
Regex.Replace(Text, "")
を繰り返せばいいのかな?


劇団しゃらら  2005-09-21 01:58:33  No: 125521

あんさん、ありがとうございます。

Dim Regexp
Set Regexp = New Regexp

strNameSP = StrConv(strNameSP, vbNarrow)
strNameSP = Replace(strNameSP, " ", "")
Regexp.Pattern = "\(.*\)"
strNameSP = Regexp.Replace(strNameSP, "")

とやってみたのですが、ユーザー定義型は定義されてませんと表示されちゃいます。どうすれば良いのでしょうか?


KG  2005-09-21 02:00:24  No: 125522

()の中にさらに()があるというようなことがなければ
あんさんの案がシンプルで良いかと思います:D


KG  2005-09-21 02:07:40  No: 125523

アーリバインドしてないのであれば、魔界の仮面弁士さんが返信してらっしゃる
ようにCreateObjectを使ってやらないといけませんね。
>Set Regexp = New Regexp

Set Regexp = CreateObject("VBScript.RegExp")
です。

>Regexp.Pattern = "\(.*\)"
これではなくて
Regexp.Pattern = "\([^\(]*\)"
()が無くなるまで置換は繰り返します。

#既に気づいて検証してらっしゃるかもしれませんが|^-^;


劇団しゃらら  2005-09-21 02:13:00  No: 125524

あんさん、KGさん、ありがとうございます!

無事に括弧内クリアができました^▽^v

Regexpを調べたら結構役に立つクラスなんですねー
勉強になります。。

今後ともお世話になると思いますが、よろしくお願いいたします。
ほんと、助かりました。ありがとうございました。


あん  2005-09-21 02:15:42  No: 125525

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")
にしてみてください


あん  2005-09-21 02:21:32  No: 125526

>Regexp.Pattern = "\([^\(]*\)"
これはちょっとあまかったです。

"abc(def(ghi)ikl(mno)pqr)stu"
が救えなかったです。


あん  2005-09-21 02:40:29  No: 125527

整理してみました。

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かな


あん  2005-09-21 02:47:12  No: 125528

>()がとじられてなく"("だけの時のエラー表示などをしたいのです。
何か良い方法はありませんでしょうか?
置換した後
If Reg.Test(Text,"[\(\)]") Then
'  エラー処理
End If
かな


劇団しゃらら  2005-09-21 02:47:25  No: 125529

あんさん、ありがとうございます。
大変わかりやすくまとめてくださって感謝です。
完璧なまでにマスターしましたよ^^


あん  2005-09-21 02:52:02  No: 125530

>If Reg.Test(Text,"[\(\)]") Then
>'  エラー処理
>End If
Reg.Pattern = "[\(\)]"
If Reg.Test(Text) Then
'  エラー処理
End If
の間違い今日は間違ってばかり・・


劇団しゃらら  2005-09-21 03:11:29  No: 125531

もしよろしかったらでいいのですが、

"\([^\(\)]*\)"  の正規表現の意味合いを教えてください。
ネット検索しましたが、なかなか詳しい解説がないものですね。。

¥の意味合いは何ですか?


KG  2005-09-21 03:24:41  No: 125532

http://www.sixnine.net/regexp/index.html

ここなどいかがですか?


劇団しゃらら  2005-09-21 04:02:13  No: 125533

参考になります。
度々ありがとうございます。。


あん  2005-09-21 04:40:43  No: 125534

>¥の意味合いは何ですか?
()は正規表現では特別な意味合いをもちます。
グルーピングといいます。
()を使用した過去ログがあります。
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200507/05070075.txt
なので()をあらわしたい場合は\(\)と記述するのです。


魔界の仮面弁士  2005-09-21 07:06:26  No: 125535

蛇足までに。

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

# うーむ。ループさせないと無理かな……。


ガッ  2005-09-21 07:36:39  No: 125536

今まで出ていないようなのでゴリゴリ版…
バグ潜んでいると思います。

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


ひろ  2005-09-21 18:51:17  No: 125537

( ) の対応関係をチェックする場合、()のネストの数に上限を設けない限り、正規表現だけでチェックするのは本質的に不可能です。
(正規文法の範囲外の文法であり、、正規表現は正規文法に合致する文法しか記述できない)

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


劇団しゃらら  2005-09-21 20:15:54  No: 125538

魔界の仮面弁士さん、ガッさん、大変参考になりました。
今後ともよろしくお願いいたします。


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

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






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