Excelで正規表現を使用して、データ操作の設定などのExcelの強力なグリッドを利用するにはどうすればよいですか。
Regexは、ExcelがLeft
、Mid
、Right
、Instr
型のコマンドを同様の操作に使用できるため、多くの状況( 正規表現を使用するかしないか? )には理想的ではないことがわかります。
正規表現 はパターンマッチングに使用されます。
Excelで使用するには、次の手順に従います。
ステップ1 : "Microsoft VBScript正規表現5.5"へのVBA参照の追加
ステップ2 :あなたのパターンを定義する
基本定義:
-
範囲。
a-z
はaからzまでの小文字に一致します0-5
は、0から5までの任意の数に一致します[]
これらの角かっこ内のオブジェクトの1つと正確に一致します。
[a]
は文字aと一致します[abc]
は、a、b、cのいずれかの文字に一致します。[a-z]
は、アルファベットの小文字1文字に一致します。()
返品を目的として、さまざまな一致をグループ化します。以下の例を参照してください。
{}
前に定義されたパターンの繰り返しコピーの乗数。
[a]{2}
は、2つの連続した小文字のaに一致します。aa
[a]{1,3}
は、最低1文字から最大3文字の小文字のa
、aa
、aaa
に一致します+
前に定義されたパターンの少なくとも1つ以上に一致します。
a+
は、連続するaのa
、aa
、aaa
などに一致します。?
その前に定義されているパターンの0個または1個に一致します。
[a-z]?
は、空の文字列または任意の1文字の小文字に一致します。*
直前に定義された0個以上のパターンに一致します。 - 例存在してもしなくてもよいパターンのワイルドカード。 - 例[a-z]*
は、空の文字列または小文字の文字列と一致します。
.
改行以外の任意の文字と一致します\n
a.
で始まり\n
以外のもので終わる2文字の文字列に一致します。|
OR演算子
a|b
は、a
またはb
のいずれかを一致させることができることを意味します。red|white|orange
は正確にいずれかの色に一致します。^
NOT演算子
[^0-9]
文字に数字を含めることはできません[^aA]
文字は小文字のa
または大文字のA
にはできません\
後に続く特殊文字をエスケープします(上記の振る舞いをオーバーライドします)
\.
、\\
、\(
、\?
、\$
、\^
アンカーパターン:
^
文字列の先頭で一致する必要があります
^a
最初の文字は小文字でなければなりませんa
^[0-9]
最初の文字は数字でなければなりません。$
文字列の末尾で一致する必要があります
a$
最後の文字は小文字でなければなりませんa
優先順位表:
Order Name Representation
1 Parentheses ( )
2 Multipliers ? + * {m,n} {m, n}?
3 Sequence & Anchors abc ^ $
4 Alternation |
定義済みの文字の省略形:
abr same as meaning
\d [0-9] Any single digit
\D [^0-9] Any single character that's not a digit
\w [a-zA-Z0-9_] Any Word character
\W [^a-zA-Z0-9_] Any non-Word character
\s [ \r\t\n\f] Any space character
\S [^ \r\t\n\f] Any non-space character
\n [\n] New line
例1 :マクロとして実行
次の例のマクロは、セルA1
の値を調べて、最初の1文字か2文字が数字かどうかを調べます。そうであれば、それらは削除され、残りの文字列が表示されます。そうでない場合は、一致が見つからないことを知らせるボックスが表示されます。 A1
のセル12abc
値はabc
を返し、1abc
の値はabc
を返し、abc123
の値は文字列の先頭にないため、 "Not Matched"を返します。
Private Sub simpleRegex()
Dim strPattern As String: strPattern = "^[0-9]{1,2}"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String
Dim Myrange As Range
Set Myrange = ActiveSheet.Range("A1")
If strPattern <> "" Then
strInput = Myrange.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
MsgBox (regEx.Replace(strInput, strReplace))
Else
MsgBox ("Not matched")
End If
End If
End Sub
例2 :セル内関数として実行
この例は例1と同じですが、セル内関数として実行するように設定されています。使用するには、コードをこれに変更します。
Function simpleCellRegex(Myrange As Range) As String
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
Dim strReplace As String
Dim strOutput As String
strPattern = "^[0-9]{1,3}"
If strPattern <> "" Then
strInput = Myrange.Value
strReplace = ""
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.test(strInput) Then
simpleCellRegex = regEx.Replace(strInput, strReplace)
Else
simpleCellRegex = "Not matched"
End If
End If
End Function
文字列( "12abc")をセルA1
に配置します。セルB1
にこの式=simpleCellRegex(A1)
を入力すると、結果は "abc"になります。
例3 :ループスルー範囲
この例は例1と同じですが、セル範囲をループします。
Private Sub simpleRegex()
Dim strPattern As String: strPattern = "^[0-9]{1,2}"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String
Dim Myrange As Range
Set Myrange = ActiveSheet.Range("A1:A5")
For Each cell In Myrange
If strPattern <> "" Then
strInput = cell.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
MsgBox (regEx.Replace(strInput, strReplace))
Else
MsgBox ("Not matched")
End If
End If
Next
End Sub
例4 :異なるパターンに分割する
この例では、範囲(A1
、A2
&A3
)をループ処理し、3桁の数字で始まり、その後に単一の英字が続き、次に4桁の数字が続くストリングを探します。 ()
を使用することで、出力はパターンマッチを隣接するセルに分割します。 $1
は、()
の最初のセット内で一致した最初のパターンを表します。
Private Sub splitUpRegexPattern()
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
Dim Myrange As Range
Set Myrange = ActiveSheet.Range("A1:A3")
For Each C In Myrange
strPattern = "(^[0-9]{3})([a-zA-Z])([0-9]{4})"
If strPattern <> "" Then
strInput = C.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
If regEx.test(strInput) Then
C.Offset(0, 1) = regEx.Replace(strInput, "$1")
C.Offset(0, 2) = regEx.Replace(strInput, "$2")
C.Offset(0, 3) = regEx.Replace(strInput, "$3")
Else
C.Offset(0, 1) = "(Not matched)"
End If
End If
Next
End Sub
結果:
追加のパターン例
String Regex Pattern Explanation
a1aaa [a-zA-Z][0-9][a-zA-Z]{3} Single alpha, single digit, three alpha characters
a1aaa [a-zA-Z]?[0-9][a-zA-Z]{3} May or may not have preceeding alpha character
a1aaa [a-zA-Z][0-9][a-zA-Z]{0,3} Single alpha, single digit, 0 to 3 alpha characters
a1aaa [a-zA-Z][0-9][a-zA-Z]* Single alpha, single digit, followed by any number of alpha characters
</i8> \<\/[a-zA-Z][0-9]\> Exact non-Word character except any single alpha followed by any single digit
Excelの数式で直接正規表現を使用するには、次のUDF(ユーザー定義関数)が役立ちます。多かれ少なかれ、Excel関数として正規表現機能を直接公開します。
2〜3個のパラメーターが必要です。
$0
、$1
、$2
などを含めることができます。 $0
は一致全体であり、$1
以上は正規表現の各一致グループに対応します。デフォルトは$0
です。メールアドレスの抽出:
=regex("Peter Gordon: [email protected], 47", "\w+@\w+\.\w+")
=regex("Peter Gordon: [email protected], 47", "\w+@\w+\.\w+", "$0")
いくつかの部分文字列の抽出:
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "E-Mail: $2, Name: $1")
結果:E-Mail: [email protected], Name: Peter Gordon
単一のセルの結合文字列を複数のセルのコンポーネントに分解するには:
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "$" & 1)
=regex("Peter Gordon: [email protected], 47", "^(.+): (.+), (\d+)$", "$" & 2)
結果:Peter Gordon
[email protected]
...
このUDFを使用するには、次の手順を実行します(おおよそ このMicrosoftページ に基づいています。追加情報があります!)。
ALT+F11
を押して、Microsoft Visual Basic for Applicationsエディターを開きます。モジュールの挿入をクリックします。モジュールに別の名前を付ける場合は、モジュールがnot以下のUDFと同じ名前を持っていることを確認してください(たとえば、モジュールRegex
関数regex
は、#NAME!エラーを引き起こします)。
中央の大きなテキストウィンドウに次を挿入します。
Function regex(strInput As String, matchPattern As String, Optional ByVal outputPattern As String = "$0") As Variant
Dim inputRegexObj As New VBScript_RegExp_55.RegExp, outputRegexObj As New VBScript_RegExp_55.RegExp, outReplaceRegexObj As New VBScript_RegExp_55.RegExp
Dim inputMatches As Object, replaceMatches As Object, replaceMatch As Object
Dim replaceNumber As Integer
With inputRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = matchPattern
End With
With outputRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "\$(\d+)"
End With
With outReplaceRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
End With
Set inputMatches = inputRegexObj.Execute(strInput)
If inputMatches.Count = 0 Then
regex = False
Else
Set replaceMatches = outputRegexObj.Execute(outputPattern)
For Each replaceMatch In replaceMatches
replaceNumber = replaceMatch.SubMatches(0)
outReplaceRegexObj.Pattern = "\$" & replaceNumber
If replaceNumber = 0 Then
outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).Value)
Else
If replaceNumber > inputMatches(0).SubMatches.Count Then
'regex = "A to high $ tag found. Largest allowed is $" & inputMatches(0).SubMatches.Count & "."
regex = CVErr(xlErrValue)
Exit Function
Else
outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).SubMatches(replaceNumber - 1))
End If
End If
Next
regex = outputPattern
End If
End Function
Microsoft Visual Basic for ApplicationsEditorウィンドウを保存して閉じます。
patszim 's answer を拡張してRushにいる人たち。
次のコードを追加してください。
Function RegxFunc(strInput As String, regexPattern As String) As String
Dim regEx As New RegExp
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.pattern = regexPattern
End With
If regEx.Test(strInput) Then
Set matches = regEx.Execute(strInput)
RegxFunc = matches(0).Value
Else
RegxFunc = "not matched"
End If
End Function
正規表現パターンはセルの1つに配置され、絶対参照が使用されます。 関数はそれが作成したワークブックに結び付けられます。
異なるワークブックで使用する必要がある場合は、関数をPersonal.XLSBに保存してください。
これが私の試みです。
Function RegParse(ByVal pattern As String, ByVal html As String)
Dim regex As RegExp
Set regex = New RegExp
With regex
.IgnoreCase = True 'ignoring cases while regex engine performs the search.
.pattern = pattern 'declaring regex pattern.
.Global = False 'restricting regex to find only first match.
If .Test(html) Then 'Testing if the pattern matches or not
mStr = .Execute(html)(0) '.Execute(html)(0) will provide the String which matches with Regex
RegParse = .Replace(mStr, "$1") '.Replace function will replace the String with whatever is in the first set of braces - $1.
Else
RegParse = "#N/A"
End If
End With
End Function
これをセル関数(SUM
やVLOOKUP
など)として使用する必要があり、それが簡単であることがわかりました。
ワークブックまたは独自のモジュールのいずれかで次の関数を作成します。
Function REGPLACE(myRange As Range, matchPattern As String, outputPattern As String) As Variant
Dim regex As New VBScript_RegExp_55.RegExp
Dim strInput As String
strInput = myRange.Value
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = matchPattern
End With
REGPLACE = regex.Replace(strInput, outputPattern)
End Function
それから=REGPLACE(B1, "(\w) (\d+)", "$1$2")
を使ってセル内で使うことができます(例: "A 243"から "A243")。
これがregex_subst()
関数です。例:
=regex_subst("watermellon", "[aeiou]", "")
---> wtrmlln
=regex_subst("watermellon", "[^aeiou]", "")
---> aeeo
これが単純化されたコードです(とにかく私にとってはもっと単純です)。上の例を使用して適切な出力パターンを作成し、私の例のように機能させる方法はわかりませんでした。
Function regex_subst( _
strInput As String _
, matchPattern As String _
, Optional ByVal replacePattern As String = "" _
) As Variant
Dim inputRegexObj As New VBScript_RegExp_55.RegExp
With inputRegexObj
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = matchPattern
End With
regex_subst = inputRegexObj.Replace(strInput, replacePattern)
End Function
スクリプトを移植可能にする必要があるため、参照ライブラリを有効にする必要はありません。 Dim foo As New VBScript_RegExp_55.RegExp
行はUser Defined Type Not Defined
エラーを引き起こしました、しかし私は私のために働いた解決策を見つけました。
あなたがしたいことはセルA1
に例の文字列を入れて、そしてあなたのstrPattern
をテストすることです。それがうまくいったら、次にrng
を調整します。
Public Sub RegExSearch()
'https://stackoverflow.com/questions/22542834/how-to-use-regular-expressions-regex-in-Microsoft-Excel-both-in-cell-and-loops
'https://wellsr.com/vba/2018/Excel/vba-regex-regular-expressions-guide/
'https://www.vitoshacademy.com/vba-regex-in-Excel/
Dim regexp As Object
'Dim regex As New VBScript_RegExp_55.regexp 'Caused "User Defined Type Not Defined" Error
Dim rng As Range, rcell As Range
Dim strInput As String, strPattern As String
Set regexp = CreateObject("vbscript.regexp")
Set rng = ActiveSheet.Range("A1:A1")
For Each rcell In rng.Cells
strPattern = "([a-z]{2})([0-9]{8})"
'Search for 2 ## then 8 Digits Eg: XY12345678 = Matched
If strPattern <> "" Then
strInput = rcell.Value
With regexp
.Global = False
.MultiLine = False
.ignoreCase = True
.Pattern = strPattern
End With
If regexp.test(strInput) Then
MsgBox rcell & " Matched in Cell " & rcell.Address
Else
MsgBox "No Matches!"
End If
End If
Next
End Sub