5

部分を抽出したい次の文字列があります。

<FONT COLOR="GREEN">201 KAR 2:340.</FONT>

この特定のケースでは、数値 201、2、および 340 を抽出したいと考えています。これらを後で連結して別の文字列を形成するために使用します。

http://www.lrc.state.ky.us/kar/201/002/340reg.htm

解決策はありますが、読みにくく、かなりぎこちないようです。これには、mid 関数の使用が含まれます。ここにあります:

intTitle = CInt(Mid(strFontTag, 
                    InStr(strFontTag, ">") + 1, 
                    (InStr(strFontTag, "KAR") - InStr(strFontTag, ">")) 
                           - 3))

このタスクにアプローチするためのより良い方法があるかどうかを知りたいです。最初の InStr 関数が何をするかを説明する intPosOfEndOfOpeningFontTag のような変数名を記述できることはわかっていますが、それでも私には扱いにくいと感じます。

ある種の分割関数、正規表現、またはまだ出会っていないよりエレガントな方法を使用する必要がありますか? 私は何年もこの方法で文字列を操作してきましたが、もっと良い方法があるに違いないと感じています。ありがとう。

4

4 に答える 4

1

クラス

Imports System
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Xml
Imports System.Xml.Linq
Imports System.Linq

Public Class clsTester
    'methods
    Public Sub New()
    End Sub

    Public Function GetTitleUsingRegEx(ByVal fpath$) As XElement
        'use this function if your input string is not a well-formed
        Dim result As New XElement(<result/>)
        Try
            Dim q = Regex.Matches(File.ReadAllText(fpath), Me.titPattern1, RegexOptions.None)
            For Each mt As Match In q
                Dim t As New XElement(<title/>)
                t.Add(New XAttribute("name", mt.Groups("name").Value))
                t.Add(New XAttribute("num1", mt.Groups("id_1").Value))
                t.Add(New XAttribute("num2", mt.Groups("id_2").Value))
                t.Add(New XAttribute("num3", mt.Groups("id_3").Value))
                t.Add(mt.Value)
                result.Add(t)
            Next mt
            Return result
        Catch ex As Exception
            result.Add(<error><%= ex.ToString %></error>)
            Return result
        End Try
    End Function

    Public Function GetTitleUsingXDocument(ByVal fpath$) As XElement
        'use this function if your input string is well-formed
        Dim result As New XElement(<result/>)
        Try
            Dim q = XElement.Load(fpath).Descendants().Where(Function(c) Regex.IsMatch(c.Name.LocalName, "(?is)^font$")).Where(Function(c) Regex.IsMatch(c.Value, Me.titPattern2, RegexOptions.None))
            For Each nd As XElement In q
                Dim s = Regex.Match(nd.Value, Me.titPattern2, RegexOptions.None)
                Dim t As New XElement(<title/>)
                t.Add(New XAttribute("name", s.Groups("name").Value))
                t.Add(New XAttribute("num1", s.Groups("id_1").Value))
                t.Add(New XAttribute("num2", s.Groups("id_2").Value))
                t.Add(New XAttribute("num3", s.Groups("id_3").Value))
                t.Add(nd.Value)
                result.Add(t)

            Next nd
            Return result
        Catch ex As Exception
            result.Add(<error><%= ex.ToString %></error>)
            Return result
        End Try
    End Function

    'fields
    Private titPattern1$ = "(?is)(?<=<font[^<>]*>)(?<id_1>\d+)\s+(?<name>[a-z]+)\s+(?<id_2>\d+):(?<id_3>\d+)(?=\.?</font>)"
    Private titPattern2$ = "(?is)^(?<id_1>\d+)\s+(?<name>[a-z]+)\s+(?<id_2>\d+):(?<id_3>\d+)\.?$"
End Class

使い方

Sub Main()
        Dim y = New clsTester().GetTitleUsingRegEx("C:\test.htm")
        If y.<error>.Count = 0 Then
            Console.WriteLine(String.Format("Result from GetTitleUsingRegEx:{0}{1}", vbCrLf, y.ToString))
        Else
            Console.WriteLine(y...<error>.First().Value)
        End If

        Console.WriteLine("")
        Dim z = New clsTester().GetTitleUsingXDocument("C:\test.htm")

        If z.<error>.Count = 0 Then
            Console.WriteLine(String.Format("Result from GetTitleUsingXDocument:{0}{1}", vbCrLf, z.ToString))
        Else
            Console.WriteLine(z...<error>.First().Value)
        End If
        Console.ReadLine()
    End Sub

お役に立てれば。

于 2012-06-30T06:49:01.680 に答える
1

正規表現パターン:<FONT[^>]*>.*?(\d+).*?(\d+).*?(\d+).*?<\/FONT>

于 2012-06-29T19:58:21.200 に答える
1
<FONT[^>]*>[^\d]*(\d+)[^\d]*(\d+):(\d+)[^\d]*</FONT>
于 2012-06-29T20:04:15.003 に答える
0

@Jean-François Corbettは正しいと思います。

関数に隠して、決して振り返らないでください

コードを次のように変更します。

intTitle = GetCodesFromColorTag("<FONT COLOR="GREEN">201 KAR 2:340.</FONT>")

新しい関数を作成します。

Public Function GetCodesFromColorTag(FontTag as String) as Integer

    Return CInt(Mid(FontTag, InStr(FontTag, ">") + 1, 
                (InStr(FontTag, "KAR") - InStr(FontTag, ">")) 
                - 3))

End Function
于 2013-03-12T19:30:21.083 に答える