英文を配列に分割するには
英文には終端文字として.と?が使われます。1行の長い英文の場合、1行の中に.や?が複数使われることがありますが、英文を区切り文字ごとに分けたい場合もあります。
VBAでは文字列の分割にSplit関数を使うことがあります。ただ、Split関数は英文を分割するのにはあまり向いていません。なぜかというと、Split関数は分割する文字自体を残さないことと、複数の文字の種類を分割できないためです。
.や?のように2種類の文字で分割したい場合にSplitを使うと、.や?自体が英文から消えてしまいますし、そもそも2種類の分割が対応していません。
そこでここでは、英文の中にある.と?があれば配列に分割するマクロを紹介します。
.と?以外の文字で分割したい場合は、後述するマクロに文字を追加するだけで対応できるようにしています。
なお、Split関数については「VBA関数:指定文字で分割して配列にする(Split)」、Split関数で区切り文字を複数使う方法については「VBAのSplit関数で区切り文字を複数使う方法」をご参照ください。
英文を分割するマクロ
以下のSplitEnglish関数は、引数で渡された英文の文字列を.と?の部分で配列に分割して返します。
例えば、「aaa? bbb. ccc. ddd?」という英文の場合は、
[aaa?]
[ bbb.]
[ ccc.]
[ ddd?]
の4つの要素を持つ配列を返します。
各行の先頭の空白文字は元の英文を分解する機能に特化するためあえて残しています。先頭の空白を除去したい場合は、このSplitEnglish関数を呼び出す側でTrim関数で除去してください。後述する使い方でTrim関数を使っていますので参考にしてください。
処理の内容ですが、英文を1文字ずつループして、それが区切り文字の.か?であるかを判定して、そうであれば配列の要素を追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
Function SplitEnglish(eng As String) As Variant Dim ar() As String '// 引数文字列を分割後の配列 Dim delimiter As String '// 区切り文字 Dim iArg As Integer '// 引数文字列のループカウンタ Dim jDelim As Integer '// 区切り文字数のループカウンタ Dim s As String '// 引数文字列の現ループの1文字 Dim bMatch As Boolean '// 引数文字列の1文字が区切り文字か判定(True:引数文字が区切り文字と一致、False:不一致) '// 区切り文字を設定 delimiter = ".?" ReDim ar(0) '// 引数文字列を1文字ずつループ For iArg = 1 To Len(eng) '// 引数文字列の現ループ文字を取得 s = Mid(eng, iArg, 1) '// 一致フラグを不一致として初期化 bMatch = False '// 区切り文字の数だけループ For jDelim = 1 To Len(delimiter) '// 引数文字列の現ループ文字と区切り文字が一致する場合 If s = Mid(delimiter, jDelim, 1) Then '// 一致フラグを一致として設定 bMatch = True '// 一致があれば以降のループは不要のためループを抜ける Exit For End If Next '// 引数文字と区切り文字が一致している場合 If bMatch = True Then '// 配列の終端に区切り文字を連結 ar(UBound(ar)) = ar(UBound(ar)) & s '// 次の配列要素を追加 ReDim Preserve ar(UBound(ar) + 1) Else '// 配列の終端に引数文字を連結 ar(UBound(ar)) = ar(UBound(ar)) & s End If Next '// 配列要素の終端の空要素を削除 If ar(0) <> "" And UBound(ar) > 1 Then ReDim Preserve ar(UBound(ar) - 1) End If SplitEnglish = ar End Function |
使い方
SplitEnglish関数に英文文字列を渡すと、.と?で配列に分解されて返されます。
SplitEnglish関数では区切り文字で分解しているだけのため、.や?の後ろに空白文字があるとそれが行の先頭文字として設定されています。
そのため、Debug.Printの出力ではTrim関数を使って分割後の英文の前後の空白文字を除去しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub SplitEnglishTest() Dim s As String Dim ar As Variant s = "Are you having internet speed issues? If you have problems, test your internet line speed. Performs speed measurement and speed diagnosis, and displays the results." ar = SplitEnglish(s) Dim v For Each v In ar Debug.Print Trim(v) Next End Sub |
実行結果(3行で出力)
Are you having internet speed issues?
If you have problems, test your internet line speed.
Performs speed measurement and speed diagnosis, and displays the results.
Debug.PrintでTrimしなかった場合の出力(.の次の空白が次の行の先頭に設定される)
[Are you having internet speed issues?]
[ If you have problems, test your internet line speed.]
[ Performs speed measurement and speed diagnosis, and displays the results.]