2012-06-29 26 views
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)) 

おそらくこのタスクにアプローチするより良い方法があるかどうかを知りたいと思います。 intPosOfEndOfOpeningFontTagのような記述的な変数名を最初のInStr関数が何を記述するかを記述することができることはわかっていますが、それでも私にとっては魅力的ではありません。

スプリット関数、正規表現、または私がまだ出くわしていないよりエレガントな方法を使用するべきですか?私はこのような形で数年間文字列を操作してきましたが、もっと良い方法が必要であると感じています。ありがとう。

+0

お奨めのactivly読みやすさを気に誰かに感謝... unforunatly私はVBを知らない。 – gbtimmon

+5

申し訳ありません、このVB.net、VBAまたはVB6ですか? – JimmyPena

+0

* VBScript *には、これらのバリアント関数がすべて使用されています。 – Bob77

答えて

1

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

1
<FONT[^>]*>[^\d]*(\d+)[^\d]*(\d+):(\d+)[^\d]*</FONT> 
+0

正規表現が何であるか知らない人もいます! –

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 

これは役に立ちます。

+0

コードを説明したり、少なくともコメントしたりできますか?明白な「結果はXYZ」ではなく、実際に求められていたよりもはるかに多いようです。 – Deanna

+0

@Deanna:あなたはコードをtiriedしましたか?短い時間で回答を投稿すると、すべてのコードに詳細をコメントすることは必ずしも可能ではありません。それはまた、質問者がそれを知るべきであることを要求する。 – Cylian

+0

それは単純な文字列抽出のための2ページのコメントのついていないブラックボックス(ひどく見えないような)コードを説明しない理由ではありません。あなたはそれ以来4ヶ月間コメントしています:) – Deanna

0

私は@ジャンフランソワコーベットが正しいと思います。

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