3

1 つの文字列と 1 行に長いテキスト (たとえば、多くの書籍に関する情報) があります。

ISBN のみを検索したい (数字のみ - 各数字は chars ISBN によって防止されます)。最初の位置でこの番号を抽出する方法のコードを見つけました。問題は、すべてのテキストに対してループを作成する方法です。このサンプル ストリームリーダーに使用できますか? 回答ありがとうございます。

例:

Sub Main()
    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 test As Integer = getLiteratura.IndexOf("ISBN")
    Dim getISBN As String = getLiteratura.Substring(test + 5, getLiteratura.IndexOf(".", test + 1) - test - 5)

    Console.Write(getISBN)
    Console.ReadKey()
End Sub
4

3 に答える 3

3

開始位置をメソッドに渡すことができるため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
于 2013-09-04T13:39:33.733 に答える
0

ここに私の解決策があります

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim outputtext As New String("")
    Dim test As Integer = 0
    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.'"
    test = getLiteratura.IndexOf("ISBN")
    Dim getISBN As String = ""
    While Not getLiteratura.Substring(test + 5, getLiteratura.IndexOf(".", test + 1) - test - 5).Length = 0
        outputtext = outputtext & getLiteratura.Substring(test + 5, getLiteratura.IndexOf(".", test + 1) - test - 5) & " : "
        If getLiteratura.Substring(test + 1).IndexOf("ISBN") = 0 Then
            Exit While
        Else
            test = test + getLiteratura.Substring(test + 1).IndexOf("ISBN")
        End If
    End While

    Label1.Text = outputtext
End Sub
于 2013-09-04T13:47:03.593 に答える