2012-06-29 21 views
5

Tôi có chuỗi sau đây mà tôi muốn trích xuất các bộ phận từ:Khá Chuỗi Manipulation

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

Trong trường hợp đặc biệt này, tôi muốn trích xuất những con số 201,2 và 340, mà tôi sau này sẽ sử dụng để tiếp nhau để tạo thành một chuỗi khác:

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

tôi có một giải pháp, nhưng nó không phải là dễ dàng có thể đọc được, và nó có vẻ khá vụng về. Nó liên quan đến việc sử dụng chức năng giữa. Đây là:

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

Tôi muốn biết liệu có lẽ có cách nào tốt hơn để tiếp cận tác vụ này không. Tôi nhận ra tôi có thể làm cho một số tên biến mô tả, như intPosOfEndOfOpeningFontTag để mô tả những gì các chức năng InStr đầu tiên không, nhưng nó vẫn cảm thấy clunky với tôi.

Tôi có nên sử dụng một số loại chức năng tách, hoặc regex hoặc một số cách thanh lịch hơn mà tôi chưa gặp phải không? Tôi đã thao túng dây trong thời trang này trong nhiều năm, và tôi chỉ cảm thấy phải có một cách tốt hơn. Cảm ơn.

+0

Gotta đánh giá cao một người activly quan tâm đến khả năng đọc ... unforunatly tôi không biết vb. – gbtimmon

+5

Xin lỗi, đây là VB.net, VBA hay VB6? – JimmyPena

+0

Trông giống như * VBScript * với tất cả các hàm Biến thể được sử dụng trong nó. – Bob77

Trả lời

1

regex mẫu: <FONT[^>]*>.*?(\d+).*?(\d+).*?(\d+).*?<\/FONT>

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

Một số người không biết biểu thức thông thường là gì! –

1

Lớp

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 

Việc sử dụng

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 

Hy vọng điều này sẽ hữu ích.

+0

Bạn có thể giải thích hoặc ít nhất là nhận xét mã của bạn không? Nó dường như làm nhiều hơn so với thực sự được yêu cầu với không rõ ràng "kết quả là XYZ". – Deanna

+0

@Deanna: bạn đã đọc mã chưa?Trong khi đăng câu trả lời trong một khoảng thời gian ngắn, không phải lúc nào cũng có thể nhận xét từng đoạn mã với các chi tiết. Nó cũng đòi hỏi người hỏi nên có kiến ​​thức về điều đó. – Cylian

+0

Đó là không có lý do để không giải thích 2 trang của hộp đen không được chú ý (và dường như quá mức cần thiết) mã cho một khai thác chuỗi đơn giản. Bạn đã có 4 tháng kể từ khi bình luận nó :) – Deanna

0

Tôi nghĩ @ Jean-François Corbett đã đúng.

Ẩn nó đi trong một chức năng và không bao giờ nhìn lại

Thay đổi mã của bạn như thế này:

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

Tạo một chức năng mới:

Public Function GetCodesFromColorTag(FontTag as String) as Integer 

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

End Function 
Các vấn đề liên quan