- Offizieller Beitrag
Hmm...ich kann mich noch dukel an den Thread damals erinnern und damals war die Callback-Variante am schnellsten.
Inzwischen muss man wohl sagen, dass StringRegExpReplace schneller ist.
Ich habe mal das Script von Bitnugger etwas geändert:
Spoiler anzeigen
AutoIt
;-- TIME_STAMP 2017-11-05 09:19:00 v 0.2
#Region ;************ Includes ************
#include <File.au3>
#EndRegion ;************ Includes ************
Global $g_iCount = 0, $g_bSaveDiff = False ; True = $sReplace1 und $sReplace2 speichern, wenn unterschiedlich
_Example()
Func _Example()
Local $hFile, $iLen, $sString = ''
Local $sText = FileRead(@ScriptDir & '\openthesaurus.txt')
$sString = $sText
;~ For $i = 1 To 9
;~ $sString &= $sText
;~ Next
$iLen = StringLen($sString)
Local $sReplace1 = $sString, $sReplace2 = $sString
Local $hTimer1 = TimerInit()
_StringRegExpReplace_Simple($sReplace1)
Local $iCount = @extended
Local $fDiff1 = TimerDiff($hTimer1)
Local $hTimer2 = TimerInit()
_StringRegExpReplace_Callback($sReplace2, '([äöüÄÖÜß])', '_MyCallbackReplace("$1")')
Local $fDiff2 = TimerDiff($hTimer2)
ConsoleWrite(StringFormat('Laenge der Textdatei = %i Bytes\r\r', $iLen))
ConsoleWrite(StringFormat('_StringRegExpReplace_Simple Substitutions = %5i Time: %f ms\r', $iCount, $fDiff1))
ConsoleWrite(StringFormat('_StringRegExpReplace_Callback Substitutions = %5i Time: %f ms\r', $g_iCount, $fDiff2))
;~ ConsoleWrite('$sReplace1 = ' & $sReplace1 & @CRLF)
;~ ConsoleWrite('$sReplace2 = ' & $sReplace2 & @CRLF & @CRLF)
Local $bSave = False
If $sReplace1 <> $sReplace2 Then
ConsoleWrite('! Ops... Zeichen stimmen nicht mehr überein!' & @CRLF)
$bSave = True
ElseIf $iCount <> $g_iCount Then
ConsoleWrite('! Ops... Länge stimmt nicht mehr überein!' & @CRLF)
$bSave = True
EndIf
If $g_bSaveDiff And $bSave Then
$hFile = FileOpen(@ScriptDir & '\Replace1.txt', $FO_OVERWRITE + $FO_ANSI)
FileWrite($hFile, $sReplace1)
FileClose($hFile)
$hFile = FileOpen(@ScriptDir & '\Replace2.txt', $FO_OVERWRITE + $FO_ANSI)
FileWrite($hFile, $sReplace2)
FileClose($hFile)
EndIf
EndFunc ;==>_Example
Func _StringRegExpReplace_Simple(ByRef $sString)
Local $iCount = 0
Local $aReplace = [['Ä', 'Ae'], ['Ö', 'Oe'], ['Ü', 'Ue'], ['ä', 'ae'], ['ö', 'oe'], ['ü', 'ue'], ['ß', 'ss']]
For $i = 0 To UBound($aReplace) - 1 Step 1
$sString = StringRegExpReplace($sString, $aReplace[$i][0], $aReplace[$i][1])
;~ $sString = StringReplace($sString, $aReplace[$i][0], $aReplace[$i][1]) ; <- langsam!
$iCount += @extended
Next
$sString = StringReplace($sString, Chr(26), "'", 0, 2)
Return SetExtended($iCount)
EndFunc ;==>_StringRegExpReplace_Simple
Func _MyCallbackReplace($_sMatch)
Local Static $sReplace = 'äöüÄÖÜß' ; durchsuchen mit StringInStr -- Pos ist Index für Replace Array
Local Static $aReplace = ['bleibt-leer', 'ae', 'oe', 'ue', 'Ae', 'Oe', 'Ue', 'ss'] ; Ersetzungen
Local $iPos = StringInStr($sReplace, $_sMatch, $STR_CASESENSE) ; Hier fehlte das $STR_CASESENSE
If $iPos = 0 Then Return $_sMatch ; kann eigentlich nicht passieren
$g_iCount += 1
Return $aReplace[$iPos]
EndFunc ;==>_MyCallbackReplace
; #FUNCTION# ====================================================================================================================
; Name ..........: _StringRegExpReplace_Callback
; Description ...: Replaces ByRef all matches in a string by manipulation of the matches in a callback function
; Parameters ....: $sString String to manipulate
; ...............: $sPattern RegExp pattern for the match
; ...............: $sCallback Callback function as string, i.e. "MyCallback('$1')" -- '$1' represents the match
; .....optional..: $sBefore String to insert before the manipulated match
; .....optional..: $sAfter String to insert after the manipulated match
; Return values .: Success 1
; ...............: Failure 0 set error = 1
; Author ........: Taz77
; ===============================================================================================================================
Func _StringRegExpReplace_Callback(ByRef $sString, $sPattern, $sCallback, $sBefore = '', $sAfter = '')
$sString = Execute("'" & StringRegExpReplace(StringReplace($sString, "'", Chr(26), 0, 2), $sPattern, $sBefore & "'&" & $sCallback & "&'" & $sAfter) & "'")
If @error Then
ConsoleWrite('_StringRegExpReplace_Callback error! Pattern: "' & $sPattern & '", Callback: "' & $sCallback & '"' & @LF)
Return SetError(1, 0, 0)
EndIf
$sString = StringReplace($sString, Chr(26), "'", 0, 2)
Return 1
EndFunc ;==>_StringRegExpReplace_Callback
Alles anzeigen
auf den Thesaurus als Textform von hier: https://www.openthesaurus.de/export/OpenThe…Textversion.zip
losgelassen und das Ergebnis sieht so aus:
Code
Laenge der Textdatei = 2675226 Bytes
_StringRegExpReplace_Simple Substitutions = 36375 Time: 163.841491 ms
_StringRegExpReplace_Callback Substitutions = 36375 Time: 466.781470 ms
Und auch wenn man die Stringlänge auf das Zehnfache erhöht (For...Next-Schleife) verhalten sich beide Funktionen zeitlich linear.