Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 11 Pro : Excel 2021)
正規表現ではパターンを知りたい
投稿日時: 24/03/06 11:45:44
投稿者: Nubo

文字列中にある「152kbit_Opus」,「160kbit_Opus」,「128kbit_AAC」などをre.Replace(cell, "")で削除したいのすが
上記の3つは、正規表現ではパターン(re.Pattern)としてどう表せますか?
 

投稿日時: 24/03/06 11:59:26
投稿者: Nubo

質問が不備でした
 パターンは1??kbit_* のような形式を希望します。
 
1?? で152、160などを網羅する
_* で_Opus,_AACなどを網羅する
 
表現が下手で判りにくいでしょうがお願いします。

回答
投稿日時: 24/03/06 12:19:13
投稿者: Suzu

Nubo さんの引用:
 パターンは1??kbit_* のような形式を希望します。
 
1?? で152、160などを網羅する
_* で_Opus,_AACなどを網羅する

 
単に「_*」 では、以降全ての文字が対象になります。
 
_Opus や、_AAC の後には、文字列は続かないのでしょうか?
続かないなら問題ありませんが
 
文字列が続くのであれば、区切りとして判断できる文字列はどうなっているのでしょうか?

回答
投稿日時: 24/03/06 12:59:10
投稿者: simple

横から失礼します。
 
・数字は三桁(頭の1を含めて)、
・"_"のあとは1個以上のアルファベット(大文字小文字を問わない)
ということなら、
re.Pattern = "1\d\d_[A-Za-z]+" でしょうか。
 
数字の桁数を問わず、1から始まる数値ということなら、
re.Pattern = "1\d+_[A-Za-z]+" でしょうか。
 
ちなみに、
"1??kbit_*" だと
・1が0ないし1個
・?は{0,1}と同義ですが、「何が」を指定しない場合の動作は不明です。
・"_"が不定数個(0個以上)続くと解釈されます。
# まあ正規表現のつもりではないんでしょうけど。

投稿日時: 24/03/06 14:44:14
投稿者: Nubo

皆さん、アドバイスありがとうございます。
 
Suzuさんへの回答
>文字列が続くのであれば、区切りとして判断できる文字列はどうなっているのでしょうか?
 
_Opus や、_AAC の後には、必ずコンマ(.)が存在してmp3と続きます。
例 : 152kbit_Opus.mp3
 
Simpleさんへの回答
>数字は三桁(頭の1を含めて)、
 すいません。
 よくよく考えてみると、頭は1,2,3の三種類が存在します。
 

回答
投稿日時: 24/03/06 16:16:51
投稿者: simple

改めて、削除したい文字列の説明をし直して下さい。

投稿日時: 24/03/06 16:25:40
投稿者: Nubo

 まとめてくださいとのアドバイスなので
 
例えば、A列に
1975 Steve Howe Beginnings\Steve Howe _Beginnings 1975 Full Album (152kbit_Opus).mp3
2005 Steve Howe - Spectrum\Steve Howe Free Rein (228kbit_AAC).mp3
1979 Steve Howe - The Steve Howe Album\Concerto in D (Second Movement) (360kbit_Opus).mp3
 
これを以下にようにB列に変換したい
 
1975 Steve Howe Beginnings\Steve Howe _Beginnings 1975 Full Album.mp3
2005 Steve Howe - Spectrum\Steve Howe Free Rein.mp3
1979 Steve Howe - The Steve Howe Album\Concerto in D (Second Movement).mp3
 
 
 考えたコードは、以下です。
    (但し、AIにコードの修正を依頼したので --->1,---->2 の部分は理解が進んでいません。)
 
 
          '指定文字を検索して削除処理
             
            '正規表現RegExpの使い方
            ' 事前バインディング
            ' Microsoft VBScript Regular Expressions 5.5
            Dim re As New RegExp
             
            Dim lastRow As Long
            Dim cell As Range
            Dim searchString As String
            Dim replaceString As String
     
            ' 検索文字列と置換文字列を定義
            re.Pattern = "\d+\s+(.*?)\\(.*?)\s+\(\d+kbit_.*?\)\.mp3"  '−−−→1
            ' 列Aの最終行を取得
            lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
     
            ' 列Aの各セルに対して処理を実行
            For Each cell In ws.Range("A1:A" & lastRow) '
                  cell.Offset(0, 1).Value = re.Replace(cell, "$1\$2.mp3")     '----->2
            Next cell
             
      End With

回答
投稿日時: 24/03/06 16:49:22
投稿者: simple

説明していないと思いますが、
とりあえず回答しておきます。
 
設定部分は
re.Pattern = "\s*\(\d+kbit_[A-Za-z]*\)"
置換部分は
cell.Offset(0, 1).Value = re.Replace(cell, "")

投稿日時: 24/03/06 17:33:30
投稿者: Nubo

回答ありがとうございます。
 
`\s*\(\d+kbit_[A-Za-z]*\)` という正規表現パターンでは、
 
- `\s*`: 0個以上の空白文字(スペース、タブ、改行など)を表します。
- `\(`: 開き括弧を表します。
- `\d+`: 1個以上の数字を表します。
- `kbit_`: "kbit_" という文字列を表します。
- `[A-Za-z]*`: 0個以上のアルファベット文字を表します。
 - \):閉じ括弧を表します。
 
この正規表現パターンは、以下のような文字列にマッチする
 
- " (256kbit_Opus) "
- " (512kbit_AAC)"
- " (128kbit_Opus) "
 
なので以下のコードでマッチした文字列が削除されるハズですが
実際は、B列にはA列と同じ文字列が出力されました。
 
            ' 検索文字列と置換文字列を定義
            re.Pattern = re.Pattern = "\s*\(\d+kbit_[A-Za-z]*\)"
            ' 列Aの最終行を取得
            lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
     
            ' 列Aの各セルに対して削除処理を実行後に変名
            For Each cell In ws.Range("A1:A" & lastRow) '
                  cell.Offset(0, 1).Value = re.Replace(cell, "")
            Next cell
 
どこか?理解がまちがっていますか ?

回答
投稿日時: 24/03/06 18:42:45
投稿者: Suzu

確認してください。
 

引用:
re.Pattern = re.Pattern = "\s*\(\d+kbit_[A-Za-z]*\)"

回答
投稿日時: 24/03/06 21:35:36
投稿者: WinArrow

正規表現を使わない方法
 
    Debug.Print Left(文字列, InStrRev(文字列, " ") - 1) & ".mp3"

回答
投稿日時: 24/03/06 22:01:16
投稿者: simple

# 返答を待っていましたが、無いようなので。
 
>どこか?理解がまちがっていますか ?
ご指摘があったとおりです。その箇所がNGです。
私の回答と違うということは、ChatGPTの提示したコードなんですか?
そうであれば、こちらの回答より、GPTの回答が正しいと思って疑いもしないところ、ですかね。
 
正規表現の説明

引用:
`\s*\(\d+kbit_[A-Za-z]*\)` という正規表現パターンでは、
  
- `\s*`: 0個以上の空白文字(スペース、タブ、改行など)を表します。
- `\(`: 開き括弧を表します。
以下略
これはChatGPTの回答ですよね。
 
それを踏まえて下記のコードを修正して下さい、とか質問したら、
' 検索文字列と置換文字列を定義
に釣られて、そのコードを回答してきたのではないですか?ここは推測ですが。
そもそも「置換文字列を定義」は、re.Replace(cell, "$1\$2.mp3")に対するコメントでしょう。
 
既に指摘いただいている箇所に問題があります。
ステップ実行すれば直ぐにわかるのですが、
re.Pattern = re.Pattern = "\s*\(\d+kbit_[A-Za-z]*\)"
右の青色部分は文字列の比較です。
re.Pattern(未設定なので"") と "\s*\(\d+kbit_[A-Za-z]*\)"を比較して、
その結果Falseを文字列変換して"False"という文字列がパターンに指定されています。
ローカルウインドウでも、reのPatternプロパティの値が確認できますし、
イミディエイトウインドウで ? re.Pattern としても確認できます。
 
GPTの回答がすべて正しいわけではないので、それを見分ける能力が必要です。
実際に確認する能力も必要です。
 
# 私見ですが、ChatGPTの回答が不審であれば、ChatGPTそのものに再質問したらどうですか?
# GPTにはチェック能力はないかもしれないが。
# もしそうなら、現時点ではその程度のものと考えて、
# 過大な期待は捨てて疑ってかかることです。

投稿日時: 24/03/07 05:24:46
投稿者: Nubo

simpleさん、返事がおくれて大変失礼しました。
 
所用でその後外出してPCを見る機会がありませんでした。
 
今朝、パターンの記載を間違えているのを指摘されて赤面の思いで恥ずかしい限りです。
(パターンの内容解析に頭が切り替わっていて
  パターンをコピペする時に位置を間違えているのを全く気がつきませんでした)
 
パターンを正規に修正して思っていた出力が書き出されました。
(これで問題は、解決しました。)
 
改めて間違いの指摘感謝いたします。
 
WinArrowさん、正規表現を使わないコードをありがとうございます。
 文字列の後部から半角のスペースを探してそれ以降を削除すると言う手法ですね。
  正規表現と変わらない出力結果がでました。
 
  

投稿日時: 24/03/07 10:53:27
投稿者: Nubo

お世話になりました。