開始位置をメソッドに渡すことができるためIndexOf
、最後の反復が中断したところから検索を開始することで、文字列をループできます。例えば:
Dim getLiteratura As String = "'Author 1. Name of book 1. ISBN 978-80-251-2025-5.', 'Author 2. Name of Book 2. ISBN 80-01-01346.', 'Author 3. Name of book. ISBN 80-85849-83.'"
Dim isbns As New List(Of String)()
Dim position As Integer = 0
While position <> -1
position = getLiteratura.IndexOf("ISBN", position)
If position <> -1 Then
Dim endPosition As Integer = getLiteratura.IndexOf(".", position + 1)
If endPosition <> -1 Then
isbns.Add(getLiteratura.Substring(position + 5, endPosition - position - 5))
End If
position = endPosition
End If
End While
データがすでにすべて文字列にロードされている場合、それはあなたが見つける可能性が高いメソッドとほぼ同じくらい効率的です。ただし、この方法は可読性や柔軟性に欠けます。これらのことが単なる効率よりも重要な場合は、RegEx の使用を検討してください。
For Each i As Match In Regex.Matches(getLiteratura, "ISBN (?<isbn>.*?)\.")
isbns.Add(i.Groups("isbn").Value)
Next
ご覧のとおり、読みやすいだけでなく、構成も可能です。パターンを外部のリソース、構成ファイル、データベースなどに保存できます。
データがまだすべて文字列に読み込まれておらず、効率が最大の関心事である場合は、ストリーム リーダーの使用を検討して、データの小さなサブセットのみを一度にメモリに読み込むことができます。そのロジックはもう少し複雑になりますが、それでもそれほど難しくはありません。
を介してそれを行う方法の簡単な例を次に示しますStreamReader
。
Dim isbns As New List(Of String)()
Using reader As StreamReader = New StreamReader(stream)
Dim builder As New StringBuilder()
Dim isbnRegEx As New Regex("ISBN (?<isbn>.*?)\.")
While Not reader.EndOfStream
Dim charValue As Integer = reader.Read()
If charValue <> -1 Then
builder.Append(Convert.ToChar(charValue))
Dim matches As MatchCollection = isbnRegEx.Matches(builder.ToString())
If matches.Count <> 0 Then
For Each i As Match In matches
isbns.Add(i.Groups("isbn").Value)
Next
builder.Clear()
End If
End If
End While
End Using
ご覧のとおり、その例では、一致が見つかるとすぐにそれをリストに追加しbuilder
、バッファとして使用されている をクリアします。そうすれば、一度にメモリに保持されるデータの量は、1 つの「レコード」のサイズを超えることはありません。
アップデート
あなたのコメントに基づいて、適切に機能させるのに問題があるため、周囲の文字なしで ISBN 番号のみを出力する完全な動作サンプルを次に示します。新しい VB.NET コンソール アプリケーションを作成し、次のコードを貼り付けるだけです。
Imports System.Text.RegularExpressions
Module Module1
Public Sub Main()
Dim data As String = "'Author 1. Name of book 1. ISBN 978-80-251-2025-5.', 'Author 2. Name of Book 2. ISBN 80-01-01346.', 'Author 3. Name of book. ISBN 80-85849-83.'"
For Each i As String In GetIsbns(data)
Console.WriteLine(i)
Next
Console.ReadKey()
End Sub
Public Function GetIsbns(data As String) As List(Of String)
Dim isbns As New List(Of String)()
For Each i As Match In Regex.Matches(data, "ISBN (?<isbn>.*?)\.")
isbns.Add(i.Groups("isbn").Value)
Next
Return isbns
End Function
End Module