|
Aus zwei mach eins - aber wie, wenn von zwei Strings der zweite
die Fortsetzung des ersten ist und sich die beiden Strings somit
überschneiden? Wie etwa könnten Sie also aus den Splittern "ABOUT
Visual" und "Visual Basic" den vollständigen String
"ABOUT Visual Basic" erhalten? Vorausgesetzt ist
natürlich, dass nicht - wie hier - bereits das gesuchte Ergebnis
bekannt ist, sondern eben lediglich die Tatsache, dass beide Teile
zusammengehören und sich gegebenenfalls überschneiden können.
Zunächst einmal müssen Sie dazu ermitteln, ob sich die beiden
Teile überhaupt überschneiden. Die folgende Funktion InStrOverlap
prüft, ob sich zwei Strings überschneiden, und gibt die Länge der
Überschneidung zurück. Im letzten optionalen Parameter InstrPos
(Sie müssen hier eine deklarierte Variable übergeben, wenn Sie die
Rückgabe dieses Werts brauchen) wird der Beginn der Überschneidung
zurückgegeben.
Sie können optional die Vergleichsmethode wählen - sowohl die
Visual Basic-Funktion InStrRev
als auch StrComp
unterstützen den Vergleich auf exakte Übereinstimmung der Zeichen
(vbCompareBinary) oder den lexikalischen Vergleich (vbCompareText).
Standardmäßig wird lediglich geprüft, ob der zweite String schon
im ersten String beginnt.
Im weiteren optionalen Parameter TestMethod können Sie zum einen
angeben, ob auch der umgekehrte Vergleich stattfinden soll (tmReverse...)
- der erste String also als Fortsetzung des zweiten
betrachtet werden soll. Wird hierbei eine Übereinstimmung
festgestellt, wird zur Unterscheidung die Länge der Überschneidung
als negativer Wert zurückgegeben. Intern macht die Funktion dabei
nichts weiter, als sich selbst mit dem über Kreuz übergebenen
String-Paar aufzurufen, und den Rückgabewert dieses Aufrufs mit minus
1 zu multiplizieren.
Ebenso können Sie in TestMethod angeben, ob die Überschneidung
auch dann zurückgegeben werden soll (...InStr), wenn
der zweite String vollständig im ersten enthalten ist. Die optional
im Parameter InstrPos zurückgegebene Position ist zur Kennzeichnung
dann negativ.
Public Enum TestMethodConstants
tmDefault
tmReverse
tmDefaultInStr
tmReverseInStr
End Enum
Public Function InStrOverlap(Str1 As String, Str2 As String, _
Optional ByVal CompareMethod As VbCompareMethod = vbBinaryCompare, _
Optional ByVal TestMethod As TestMethodConstants, _
Optional InStrPos As Long) As Long
Dim nPos As Long
Dim nLen As Long
nPos = InStrRev(Str1, Left$(Str2, 1), , CompareMethod)
If nPos Then
nLen = Len(Str1) - nPos + 1
If StrComp(Left$(Str2, nLen), Mid$(Str1, nPos), CompareMethod) = 0 Then
InStrOverlap = nLen
InStrPos = nPos
ElseIf TestMethod = tmDefaultInStr Then
If InStrRev(Str1, Str2, , CompareMethod) Then
InStrOverlap = Len(Str2)
InStrPos = nPos * -1
End If
End If
ElseIf (TestMethod And tmReverse) = tmReverse Then
InStrOverlap = -1 * InStrOverlap(Str2, Str1, CompareMethod, _
TestMethod, InStrPos)
End If
End Function
Das Zusammenfügen der sich gegebenenfalls überlappenden Strings
ist an sich keine sonderlich anspruchsvolle Aufgabe. Da aber diverse
Fallunterscheidungen notwendig sind, stellen wir Ihnen
praktischerweise auch die passende Funktion dafür zur Verfügung.
Der Funktion ConcatenateOverlapped übergeben Sie wieder die
beiden Strings und gegebenenfalls die Vergleichsmethode und wie bei
InstrOverlap die Testmethode. Weiterhin können Sie im Parameter
OverlapMethod optional angeben, ob der Teil der Überschneidung vom
ersten oder vom zweiten String übernommen werden soll - beim
lexikalischen Vergleich und tatsächlich unterschiedlichen
Schreibweisen kann diese Angabe von Bedeutung sein. Im letzten
optionalen Parameter OnlyIfOverlapped geben Sie schließlich
gegebenenfalls noch an, ob die zwei Strings nur zusammengefügt
werden sollen, wenn sie sich überschneiden, oder ob sie in jedem
Fall zusammengefügt werden sollen.
Public Enum OverlapMethodConstants
omLeftPart
omRightPart
End Enum
Public Function ConcatenateOverlapped(Str1 As String, Str2 As String, _
Optional ByVal CompareMethod As VbCompareMethod = vbBinaryCompare, _
Optional ByVal TestMethod As TestMethodConstants, _
Optional ByVal OverlapMethod As OverlapMethodConstants = omLeftPart, _
Optional ByVal OnlyIfOverlapped As Boolean) As String
Dim nLen As Long
Dim nPos As Long
Dim nStr As String
If Len(Str1) = 0 Then
If Not OnlyIfOverlapped Then
ConcatenateOverlapped = Str2
Exit Function
End If
End If
If Len(Str2) = 0 Then
If Not OnlyIfOverlapped Then
ConcatenateOverlapped = Str1
Exit Function
End If
End If
nLen = InStrOverlap(Str1, Str2, CompareMethod, TestMethod, nPos)
Select Case Abs(nLen)
Case Len(Str2)
Select Case Sgn(nLen)
Case -1
' Str1 ist in Str2 enthalten
Select Case OverlapMethod
Case omLeftPart
nStr = Str2
Mid$(nStr, Abs(nPos)) = Str1
ConcatenateOverlapped = nStr
Case omRightPart
ConcatenateOverlapped = Str2
End Select
Case 1
' Str2 ist in Str1 enthalten
Select Case OverlapMethod
Case omLeftPart
ConcatenateOverlapped = Str1
Case omRightPart
nStr = Str1
Mid$(nStr, Abs(nPos)) = Str2
ConcatenateOverlapped = nStr
End Select
End Select
Case Is > 0
Select Case Sgn(nLen)
Case -1
' Str1 folgt überschneidend auf Str2
Select Case OverlapMethod
Case omLeftPart
ConcatenateOverlapped = Str2 & Mid$(Str1, Abs(nLen) + 1)
Case omRightPart
ConcatenateOverlapped = Left$(Str2, nPos - 1) & Str1
End Select
Case 1
' Str2 folgt überschneidend auf Str1
Select Case OverlapMethod
Case omLeftPart
ConcatenateOverlapped = Str1 & Mid$(Str2, nLen + 1)
Case omRightPart
ConcatenateOverlapped = Left$(Str1, nPos - 1) & Str2
End Select
End Select
ElseIf Not OnlyIfOverlapped Then
ConcatenateOverlapped = Str1 & Str2
End If
End Function
|