Regex *komprimieren*

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Phreak87.

    Regex *komprimieren*

    Hallo Leute,

    wie würdet ihr am geschicktesten vorgehen, um ein Regex zu "komprimieren" ...
    Sprich aus einer Zeichenfolge (nehmen wir an "ABCDEFGKLMabcstlk123490" mit Pipes
    dazwischen (also ein Buchstabe / Zahl der Auswahl)) folgenden dem Beispiel entsprechenden
    String "A-G|K-M|a-c|s|t|l|k|0-4|9" zu erzeugen ?
    naja ... was will ich ... ist eig. schon genau beschrieben ... ich will eine Funktion, die mir ein
    Regex Pattern "umformt" und somit "komprimiert" auf die Zeichenlänge + lesbarkeit optimiert eben ...

    die langen Regex-Zeichenketten für Zeichengruppen nerven mich einfach und ich möchte das ganze
    Inhaltlich besser lesbar darstellen ...
    Hier mal der Source, wie es funktionieren sollte ... ist noch nicht so ganz ausgereift,
    geht aber schon ...

    VB.NET-Quellcode

    1. Public Shared Function CleanRegex(Pattern As String) As String
    2. Dim Pattern_Out As New System.Text.StringBuilder
    3. Dim RGXCol As System.Text.RegularExpressions.MatchCollection = System.Text.RegularExpressions.Regex.Matches(Pattern, "\(.*?\)")
    4. For Each Match As System.Text.RegularExpressions.Match In RGXCol
    5. Dim Liste As New List(Of String)
    6. Dim ListeASC As New List(Of Integer)
    7. Dim Reserve As New List(Of String)
    8. Liste = Split(Mid(Match.Value, 2, Len(Match.Value) - 2), "|").ToList
    9. For Each Satz As String In Liste.Distinct
    10. If Trim(Satz) <> "" And Len(CStr(Satz)) = 1 Then
    11. ListeASC.Add(Asc(Satz))
    12. Else
    13. Reserve.Add(Satz)
    14. End If
    15. Next
    16. If ListeASC.Count > 0 Then
    17. Pattern_Out.Append("(")
    18. Pattern_Out.Append(CreatePatternPart(ListeASC, 0, 47, True)) ' SZ1
    19. Pattern_Out.Append(CreatePatternPart(ListeASC, 48, 57)) ' Zahlen
    20. Pattern_Out.Append(CreatePatternPart(ListeASC, 58, 64, True)) ' SZ2
    21. Pattern_Out.Append(CreatePatternPart(ListeASC, 65, 90)) ' Buchstaben groß
    22. Pattern_Out.Append(CreatePatternPart(ListeASC, 91, 96, True)) ' SZ3
    23. Pattern_Out.Append(CreatePatternPart(ListeASC, 97, 122)) ' Buchstaben klein
    24. Pattern_Out.Append(CreatePatternPart(ListeASC, 123, 127, True)) ' SZ1
    25. For Each satz As String In Reserve
    26. Pattern_Out.Append(satz & "|")
    27. Next
    28. Pattern_Out.Append(")")
    29. Pattern = Pattern.Replace(Match.Value, Replace(Pattern_Out.ToString, "|)", ")"))
    30. Pattern_Out.Clear()
    31. End If
    32. Next
    33. Return (Pattern)
    34. End Function
    35. Private Shared Function CreatePatternPart(ListeASC As List(Of Integer), Von As Int16, Bis As Int16, Optional Anfügen As Boolean = False) As String
    36. Dim Pattern_OUt As New System.Text.StringBuilder
    37. If Anfügen = False Then
    38. Dim MinAsc As Int16 = 0
    39. Dim MaxAsc As Int16 = 0
    40. For i As Int16 = Von To Bis
    41. If ListeASC.Contains(i) = False Then
    42. If MinAsc > 0 Then
    43. If MinAsc = MaxAsc Then
    44. Pattern_OUt.Append(Chr(MinAsc))
    45. Else
    46. Pattern_OUt.Append(Chr(MinAsc) & "-" & Chr(MaxAsc))
    47. End If
    48. MinAsc = 0
    49. End If
    50. Else
    51. If MinAsc = 0 Then MinAsc = i
    52. If Bis = i Then
    53. If MinAsc = i Then
    54. Pattern_OUt.Append(Chr(i))
    55. Else
    56. Pattern_OUt.Append(Chr(MinAsc) & "-" & Chr(i))
    57. End If
    58. End If
    59. MaxAsc = i
    60. End If
    61. Next
    62. Else
    63. For i As Int16 = Von To Bis
    64. If ListeASC.Contains(i) = True Then
    65. Pattern_OUt.Append(Chr(i) & "|")
    66. End If
    67. Next
    68. End If
    69. Return Pattern_OUt.ToString
    70. End Function

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Phreak87“ ()

    Ähm - und ich könnte mich drauf verlassen, wennich das etwa

    Quellcode

    1. "(?<Date>.+?)(?<Time>\s\d{2}:\d{2}:\d{2}).+?(?<HostIp>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*?(?<ProcessID>Anxilion:)(.+?[0-9]+\]:)?\W*(?<Several>.*)"

    als Pattern eingebe, dass dein Code den Pattern iwie verbessert, ohne ihn kaputt zu machen?
    Bei deinem Pattern würde genau das gleiche rauskommen ... :D

    Es werden nur einzelne Zeichen in Klammern zu Bereichen zusammengefasst ...
    also ein (A|B|C) wird zu (A-C) ... Der Rest bleibt unangetastet ...
    wenn du also in der Klammer kein Pipe verwendest passiert gar nix .

    Des ganze ist für eine Funktion für das Projekt der automatischen Patternerstellung ...
    und da hab ichs mir einfach gemacht und variable Zeichen mit Pipe in der Klammer getrennt ..

    Also bei meinen Tests hat alles funktioniert ... ausnahmen bestätigen sicher mal wieder die Regel :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Phreak87“ ()

    Hallo :)

    ich mal wieder ... Regex komprimieren funktioniert jetzt Problemlos ...
    jetzt bin ich bei Schritt 2, bei dem mir (wieder mal) die Ideen ausgehen ...

    Wenn ich eine Liste mit Wörtern habe, die sich *überschneiden*
    ein, kein, klein, einstein, steinbruch, einbruch... dann enthält jedes Wort "ein",
    jedoch bei einstein und steinbruch ist "stein" die Menge, die das Pattern
    um mehr Zeichen verkleinert ....

    jetzt möchte ich das kleinste gemeinsame Pattern für die Wörter finden ...
    (k)?(l)?ein(stein)?(bruch)? bzw. (k|kl)?ein(stein)?(bruch)?

    Hat irgendwer Ideen, wie ich das am geschicktesten erreichen kann ?