2016-09-06 5 views
0

- 私VBA正規表現にかなり新しいが、このstackoverflow threadのおかげで、VBA正規表現は、複数のパターンをidentifiying - エクセル

を、私はそれを取得しています。私は問題があり、誰かが助けてくれることを願っています。 Excelの行1では、都市/国の属性が異なる複数の文字列があります。例:私は今持っているしたい何

A1: "/flights/munich/newyork" 
A2: "flights/munich/usa" 
A3: "flights/usa/germany" 
... 

、正規表現でこれらの文字列かかわらなり、正規表現が満たされた場合に分類値を促しVBAです。例:今

A1: "/flights/munich/new-york" categorises as "city to city" 
A2: "flights/munich/usa" categorises as "city to country" 
A3: "flights/usa/germany" categorises as "country to country" 

、私は私に、「都市の都市へ」のカテゴリを返しますコードを持っているが、私は複数のパターンを処理し、対応を返すコードを取得する人を見つけ出すcan't出力文字列。要するに

、このようなロジックが必要とされている:

A1は、正規表現".*/munich/new-york"含まれている場合、A1は、正規表現".*/munich/usa"含まれている場合は、次にように出力文字列"city to country"を返すと、出力文字列"city to city"を返します。

これは、VBAで複数のパターンを持つ複数のif文をどのように処理するのかとは関係がありますが、わかりません。

これは私のコードが現在どのように表示されているかを示しています。

Function simpleCellRegex(Myrange As Range) As String 
    Dim regEx As New RegExp 
    Dim strPattern As String 
    Dim strInput As String 
    Dim strReplace As String 
    Dim strOutput As String 

    strPattern = "(munich|berlin|new-york|porto|copenhagen|moscow)/(munich|berlin|new-york|porto|copenhagen|moscow)" 

    If strPattern <> "" Then 
     strInput = Myrange.Value 
     strReplace = "CITY TO CITY" 

     With regEx 
      .Global = True 
      .MultiLine = True 
      .IgnoreCase = False 
      .Pattern = strPattern 
     End With 

     If regEx.Test(strInput) Then 
      simpleCellRegex = regEx.Replace(strInput, strReplace) 
     Else 
      simpleCellRegex = "NO MATCH FOUND" 
     End If 
    End If 

End Function 
+1

**この正規表現**を実行しようとしていますか?あなたが3つの表現でそれをやっていることを理解したように思えます。すべてのRegExの返品は、1つの一致が発生したかどうか、そして何が何であるかということです。 – dbmitch

+0

regexを使用する説得力のある理由はありますか?特に、あなたの文字列には十分に確立されたセパレータがあるため、迅速なトークン抽出機能はすぐに機能します。 – PeterT

+0

@dbmitchいいえ、文字列には複数の組み合わせが含まれているため、複数のRegex式が存在します。ピーター、特別な理由はない - 私はあなたの提案を調べるべきだと思う。ありがとう! –

答えて

0

@dbmitchがコメントに書いているように、あなたは1つのRegexでこれを行うことはできません。そのうちの3つを使う必要があります。私は個人的に都市と国をConstsに入れて、必要に応じてパターンを作成します。その後、simpleCellRegexへパラメータとしての機能(strReplaceと一緒に)それらを渡すことができます。

foo = simpleCellRegex(someRange, "CITY TO CITY", CITIES & "/" & CITIES) 
foo = simpleCellRegex(someRange, "CITY TO COUNTRY", CITIES & "/" & COUNTRIES) 
foo = simpleCellRegex(someRange, "COUNTRY TO COUNTRY", COUNTRIES & "/" & COUNTRIES) 

注:次のように呼び出され

Const CITIES As String = "(munich|berlin|new-york|porto|copenhagen|moscow)" 
Const COUNTRIES As String = "(germany|france|usa|russia|etc)" 

Function simpleCellRegex(Myrange As Range, strReplace As String, strPattern As String) As String 
    Dim regEx As New RegExp 
    Dim strPattern As String 
    Dim strInput As String 
    Dim strReplace As String 
    Dim strOutput As String 

    If strPattern <> "" Then 
     strInput = Myrange.Value 

     With regEx 
      .Global = True 
      .MultiLine = True 
      .IgnoreCase = False 
      .Pattern = strPattern 
     End With 

     If regEx.test(strInput) Then 
      simpleCellRegex = regEx.Replace(strInput, strReplace) 
     Else 
      simpleCellRegex = "NO MATCH FOUND" 
     End If 
    End If 
End Function 

あなたはループでこれをやっている場合は、それをRegExp1回を作成してから、そのをパターンの代わりに渡すだけです。

0

少し(多分)「ボックスのうち」解決策:

Option Explicit 

Sub main() 
    Const CITIES As String = "MUNICH|BERLIN|NEWYORK|PORTO|COPENHAGEN|MOSCOW" 
    Const COUNTRIES As String = "USA|GERMANY" 

    With Worksheets("FLIGHTS") 
     With .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)) 
      With .Offset(, 1) 
       .value = .Offset(, -1).value 
       .Replace What:="*flights/", replacement:="", LookAt:=xlPart, MatchCase:=False 
       .Replace What:="/", replacement:=" to ", LookAt:=xlPart, MatchCase:=False 
       ReplaceElement .Cells, CITIES, "city" 
       ReplaceElement .Cells, COUNTRIES, "country" 
      End With 
     End With 
    End With 
End Sub 

Sub ReplaceElement(rng As Range, whats As String, replacement As String) 
    Dim elem As Variant 

    With rng 
     For Each elem In Split(whats, "|") 
      .Replace What:=elem, replacement:=replacement, LookAt:=xlPart, MatchCase:=False 
     Next elem 
    End With 
End Sub 

ノート

  • は(置き換え)メソッドは、名前の間の一貫性を持っているケースを無視するが、用心するを教えることができます: "newyork"は "new-york"と決して一致しません
0

私は少し違ったやり方をします。 正規表現のパターンを開始点または終了点にし、コンマで区切られた都市または国の文字列と照合します。

あなたが提示したことを考えると、開始点と終了点は常に最後の2つの/分離単位になります。以下のような

だから、何か:時々そうであるように

Option Explicit 
Sub CategorizeFlights() 
    Dim rData As Range, vData As Variant 
    Dim arrCity() As Variant 
    Dim arrCountry() As Variant 
    Dim I As Long, J As Long 
    Dim sCategoryStart As String, sCategoryEnd As String 
    Dim V As Variant 
    Dim RE As RegExp 

arrCity = Array("munich", "newyork") 
arrCountry = Array("usa", "germany") 

Set RE = New RegExp 
With RE 
    .Global = False 
    .ignorecase = True 
End With 

Set rData = Range("A2", Cells(Rows.Count, "A").End(xlUp)).Resize(columnsize:=2) 
vData = rData 

For I = 1 To UBound(vData, 1) 
    V = Split(vData(I, 1), "/") 

     RE.Pattern = "\b" & V(UBound(V) - 1) & "\b" 
     If RE.test(Join(arrCity, ",")) = True Then 
       sCategoryStart = "City to " 
     ElseIf RE.test(Join(arrCountry, ",")) = True Then 
       sCategoryStart = "Country to " 
     Else 
       sCategoryStart = "Unknown to " 
     End If 

     RE.Pattern = "\b" & V(UBound(V)) & "\b" 
     If RE.test(Join(arrCity, ",")) = True Then 
       sCategoryEnd = "City" 
     ElseIf RE.test(Join(arrCountry, ",")) = True Then 
       sCategoryEnd = "Country" 
     Else 
       sCategoryEnd = "Unknown" 
     End If 

    vData(I, 2) = sCategoryStart & sCategoryEnd 
Next I 

With rData 
    .Value = vData 
    .EntireColumn.AutoFit 
End With 

End Sub 

、同様のアルゴリズムでは、正規表現せずに使用することができますが、私は、これは、その使用中の運動であると仮定します。