Wenn ich mehr mit RegEx mache, komm ich bis jetzt auf 22 Zeilen incl. Func und Endfunc.
//Edit: 15 Zeilen allein hab ich für das ganze Array und Delimiter-Zeigs verbraten. Der Rest kommt auf 5 Zeilen
µit - Juli
-
-
Hab jetzt 16 Zeilen inklusive Func und EndFunc und es läuft immer noch einwandfrei durch
Wann ist denn Abgabetermin?
-
18 Zeilen (mit Potential auf 16) und jedenfalls die Testsuite geschafft^^
Hatte gigantische Konstruktionen von RegEx-Pattern geschnitzt bis ich eben drauf kam, dass es dafür Kurzformen gibt....schade, so sieht das viel zu simpel aus, ist aber wesentlich schneller. -
Bin jetzt auf 15 Zeilen, mehr (weniger :)) glaub ich schaff ich nicht mehr!
-
Habe gerade den Test mit der 1,7MB-Datei gemacht wie oben beschrieben....omfg 6 Sekunden mit dem "gekürzten" Script (ungekürzt 0,7 Sek)!
Ich werde ühl oder wobel wohl 2 Scripte einsenden, ein schnelles und ein kurzes. -
Hab das auch mal getestet. Also eine 16.3 MB Text-Datei nach 'und' durchsucht und zwar Case Sensitive --> 0.461 Sekunden, 10716 'und' enthalten.
-
Zitat
$bPartialTrue = Suchbegriff auch als Teilstring / False = Suchbegriff alleinstehend
Ist mittlerweile festgelegt welche Zeichen vor und hinter dem Suchbegriff erlaubt sind, um $bpartial=True zu matchen?
In der Testsuite bekommt man jedenfalls schon mit dem Test auf Wortgrenzen 100% Erfolg, das kanns ja wohl nicht sein! -
- Offizieller Beitrag
Eine weitere Frage drängt sich auf:
Wenn $sSearch = Leerstring, dann sollen alle Zeichen gezählt werden.
Sollen in diesem Fall auch die @lf,@cr und/oder Leerzeichen mitgezählt werden.
Das wäre dann kein Unterschied zu StringLen!
Mit der momentanen Testsuite wird ja derselbe Wert, wie bei StringLen ermittelt. Soll das nun so bleiben oder wollen wir uns von StringLen abgrenzen und uns auf die sichtbaren Zeichen beschränken (also auch Leerzeichen aber kein @LF, @CR) ? Das wäre dann auch die Zählweise, wie sie in Word verwendet wird. Ist m.E. praxisnäher. -
hi,
Ich stell mal mein Script online...
Auch getestet an großen Textdateien, scheint zu funktionieren^^, die "kurze" Version hatte üble Performance-Probleme bei extrem langen Texten.ciao
AndySpoiler anzeigen
[autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]$sText = "Und Bund rund Undelete und Fundbüro; Und. und! und? und'" & ' und" ' & "Und" & @LF & "Rund" & @CR & "Rund" & @CRLF & "Rund;" & @CRLF & "Aber Aberglaube labern makaber aber"
[/autoit] [autoit][/autoit] [autoit]$t = TimerInit()
[/autoit] [autoit][/autoit] [autoit]_Check(1, _StringinStrCount("test TEST Test TestTest", "Test", False, False, "", False), 3)
[/autoit] [autoit][/autoit] [autoit]
_Check(2, _StringinStrCount("test TEST Test TestTest", "Test", True, False, "", False), 1)
_Check(3, _StringinStrCount("test TEST Test TestTest", "Test", False, True, "", False), 5)
_Check(4, _StringinStrCount("test TEST Test TestTest", "Test", True, True, "", False), 3)
_Check(5, _StringinStrCount("test TEST Test TestTest", "TEST Test", True, True, "", False), 1)
_Check(6, _StringinStrCount("test TEST Test TestTest", "TEST Test", True, True, " ", False), 4)
_Check(7, _StringinStrCount("test TEST Test TestTest", "TEST Test", True, False, " ", False), 2)
_Check(8, _StringinStrCount("test TEST Test TestTest", "TEST Test", False, False, " ", False), 6)
_Check(9, _StringinStrCount("testXTESTXTestXTestTest", "", False, False, "X", False), 20)
_Check(10, _StringinStrCount("test TEST Test TestTest", "", False, False, "", False), 23)
_Check(11, _StringinStrCount("test TEST Test TestTest", "", False, False, "", True), "1;23")
_Check(12, _StringinStrCount("test TEST Test TestTest", "", False, False, " ", True), "1;20")
_Check(13, _StringinStrCount("test TEST Test TestTest", "TEST Test", False, False, "", True), "1;1")
_Check(14, _StringinStrCount("test TEST Test TestTest", "TEST Test", False, False, " ", True), "2;3;3")
_Check(15, _StringinStrCount("test TEST Test TestTest", "T;EST", False, False, ";", True), "2;0;0")
_Check(16, _StringinStrCount("test TEST Test TestTest", "T;E,S", False, False, ";,", True), "3;0;0;0")
_Check(17, _StringinStrCount("Testat, testen, Test, Attest. Ostestland", "Test", False, False, "", False), 1)_Check(1, _StringinStrCount($sText, "und", False, False, "", False),
[/autoit] [autoit][/autoit] [autoit]
_Check(2, _StringinStrCount($sText, "und", True, False, "", False), 5)
_Check(3, _StringinStrCount($sText, "und", True, True, "", False), 11)
_Check(4, _StringinStrCount($sText, "und", False, True, "", False), 15)_Check(5, _StringinStrCount($sText, "aber", False, False, "", False), 2)
[/autoit] [autoit][/autoit] [autoit]
_Check(6, _StringinStrCount($sText, "aber", True, False, "", False), 1)
_Check(7, _StringinStrCount($sText, "aber", True, True, "", False), 3)
_Check(8, _StringinStrCount($sText, "aber", False, True, "", False), 5)_Check(9, _StringinStrCount($sText, "und;aber", False, False, ";", False), 10)
[/autoit] [autoit][/autoit] [autoit]
_Check(10, _StringinStrCount($sText, "und;aber", True, False, ";", False), 6)
_Check(11, _StringinStrCount($sText, "und;aber", True, True, ";", False), 14)
_Check(12, _StringinStrCount($sText, "und;aber", False, True, ";", False), 20)_Check(13, _StringinStrCount($sText, "und;aber", False, False, ";", True), "2;8;2")
[/autoit] [autoit][/autoit] [autoit]
_Check(14, _StringinStrCount($sText, "und;aber", True, False, ";", True), "2;5;1")
_Check(15, _StringinStrCount($sText, "und;aber", True, True, ";", True), "2;11;3")
_Check(16, _StringinStrCount($sText, "und;aber", False, True, ";", True), "2;15;5")_Check(17, _StringinStrCount($sText, "", False, True, "", False), 119)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_Check(17, _StringinStrCount($sText, "", False, True, " ", False), 104)
ConsoleWrite(TimerDiff($t) / 1000 & @CRLF)
ExitFunc _StringinStrCount($string, $SubString, $bSense = False, $bPartial = False, $sdelim = '', $bReturn = False)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
Local $casesense = "(?-i)", $part1 = "", $part2 = "", $treffer = 0 ;würde auch noch in die nächste zeile passen
Dim $retarray1[2] = [1, StringLen($string)], $retarray[1], $aSplit[1] = [$SubString]
If $SubString = "" And $sdelim = "" And $bReturn = False Then Return StringLen($string) ; :o)
If $SubString = "" And $sdelim = "" Then Return $retarray1
If $SubString = "" And $bReturn = False Then Return UBound(StringRegExp($string, "[^(" & $sdelim & ")]", 3))
If $SubString = "" Then
Dim $retarray2[2] = [1, UBound(StringRegExp($string, "[^(" & $sdelim & ")]", 3))]
Return $retarray2
EndIf
If $sdelim <> "" Then Dim $aSplit = StringSplit($SubString, $sdelim, 2) ;wird der Substring mit dem Trennzeichen gesplittet in ein nullbasiertes Array
If $bSense = False Then $casesense = "(?i)"
If $bPartial = False Then ;der suchbegriff muss alleinstehend sein
$part1 = "(?<![\d|\x{041}-\x{0ff}])" ;vornedran dürfen nur zeichen kleiner ascii0x41 sein aber keine zahlen
$part2 = "(?![\d|\x{041}-\x{0ff}])" ;hintendran dürfen nur leerzeichen sein und satzzeichen oder das textende
EndIf
For $i = 0 To UBound($aSplit) - 1 ;Zählschleife für das splitarray von null bis zur anzahl splitstrings
If $bReturn = False Then $treffer += UBound(StringRegExp($string, $casesense & $part1 & "(" & $aSplit[$i] & ")" & $part2, 3))
ReDim $retarray[UBound($retarray) + 1]
$retarray[0] += 1
$retarray[UBound($retarray) - 1] = UBound(StringRegExp($string, $casesense & $part1 & "(" & $aSplit[$i] & ")" & $part2, 3))
Next
If $bReturn = True Then Return $retarray
Return $treffer
EndFunc ;==>_StringinStrCountFunc _Check($i, $j, $k)
[/autoit]
Local $sj = "", $sk = ""
ConsoleWrite("Test " & $i & ": ")
Switch StringInStr($k, ";")
Case False
If $j = $k Then
ConsoleWrite(" Richtig: " & @TAB & $j & @LF)
Else
ConsoleWrite(" Falsch: " & @TAB & $j & @TAB & " (richtig wäre: " & $k & ")" & @LF)
EndIf
Case Else
$k = StringSplit($k, ";", 2)
If Not IsArray($j) Then
ConsoleWrite(" Falsch: " & @TAB & " Rückgabe ist kein Array" & @LF)
Return
EndIf
If UBound($j) <> UBound($k) Then
For $l = 0 To UBound($j) - 1
$sj &= " " & $j[$l]
Next
For $l = 0 To UBound($k) - 1
$sk &= " " & $k[$l]
Next
ConsoleWrite(" Falsch: " & @TAB & $sj & @TAB & " (richtig wäre: " & $sk & ")" & @LF)
Return
EndIf
Local $bRichtig = True
For $l = 0 To UBound($j) - 1
If $j[$l] <> $k[$l] Then $bRichtig = False
$sj &= " " & $j[$l]
$sk &= " " & $k[$l]
Next
If $bRichtig Then
ConsoleWrite(" Richtig: " & @TAB & $sk & @LF)
Else
ConsoleWrite(" Falsch: " & @TAB & $sj & @TAB & " (richtig wäre: " & $sk & ")" & @LF)
EndIf
EndSwitch
EndFunc ;==>_Check -
- Offizieller Beitrag
Ich stell mal mein Script online...
Finde ich eigentlich nicht so gut. Das sollte doch ein Wettbewerb sein. -
Hallo BugFix,
ZitatDas sollte doch ein Wettbewerb sein.
Wenn sich 2 Wochen lang niemand meldet und meine Fragen zum Thema immer noch offen stehen, dann gibt es aus meiner Sicht zwei Möglichkeiten:
1.) Der Wettbewerb ist "eingeschlafen", der Threadersteller hat ggf. schon eine andere "Lösung" seines Problems gefunden und keine Lust mehr weiterzumachen.
2.) Niemand hält meine Fragen zum Thema für so wichtig, daß sie beantwortet/kommentiert werden müssten.
In beiden Fällen gibt es für mich bzw mein Script keinerlei Verbesserungspotential, und bevor ich es auch noch "vergesse", stelle ich es lieber online. Ggf kann es ja jemand gebrauchen.
Sorry falls ich damit den Wettbewerb gestört haben sollte, aber ich glaube auch kaum, dass ich mit meinem Script auch nur eine ansatzweise Chance hätte.
ciao
Andy -
1.) Der Wettbewerb ist "eingeschlafen", der Threadersteller hat ggf. schon eine andere "Lösung" seines Problems gefunden und keine Lust mehr weiterzumachen.
Du hast den Sinn nicht verstanden...
Der Wettbewerb geht den ganzen Juli durch ... man muss doch nicht andauernd was dazu schreiben und man versucht eben bis zum Ende sein Skript zu optimieren. Erst dann stellt man es verschlüsselt online und schickt der Jury das Passwort. -
Wenn sich 2 Wochen lang niemand meldet...
Ich war tatsächlich fast 2 Wochen nicht mehr im Forum. Hab grad ziemlich viel um die Ohren...
Vielleicht kann ja von euch jemand ein Machtwort sprechen, um die offenen Fragen zu klären!?Sorry, ich krieg meinen Kopf dafür grad nicht frei!
lgE
-
- Offizieller Beitrag
Wie viele von euch haben denn mitgemacht?
Ich habe leider den Abgabetermin etwas verschlafen (mein Script war schon lange fertig, habe aber vergessen es eukalyptus zu schicken). Das habe ich heute mal nachgeholt (hoffe, das zählt noch). -
- Offizieller Beitrag
Ich habe leider den Abgabetermin etwas verschlafen (mein Script war schon lange fertig
Oops, geht mir genauso. Ich schicke es mal noch schnell rein. -
-
da bleibt mir doch nur ein
ciao
Andy
Hmm, dieses Mal ists irgendwie nicht so toll gelaufen... Ich hab meins kaputt optimiert und die Sicherungskopie vergessenZitat von Andyund bevor ich es auch noch "vergesse", stelle ich es lieber online
-> das ist ja auch in Ordnung, aber bitte in Zukunft verschlüssselt mit PW an die Jury -
Als erstes hat mich sehr erstaunt, wie kompakt ihr alle eure Scripte bekommen habt.
Meine Funktion (zum testen der TestSuite) hatte z.b. über 40 Zeilen!Andy: 25 Zeilen
BugFix: 22 Zeilen
Oscar: 18 Zeilen
Funkey: 16 ZeilenFunkey liegt hier mit 16 Zeilen vorne.
Allerdings hat Oscar mit 889 Bytes das schlankere Script erstellt. (Funkey: 1115 Bytes)Dieser Bytevergleich ist natürlich abhängig von den längen der Variablennamen usw... Aber vergleicht selbst...
Um die Geschwindigkeit zu messen, habe ich die Testsuite 5000 durchlaufen lassen.
Bei diesem Test schlägt nun Bugfix´s Script zu:Oscar: 11703 ms
Andy: 11402 ms
Funkey: 10349 ms
BugFix: 7796 msEin heißer Kampf um Platz 2, aber Bugfix ist nicht mehr einzuholen
Scripte:
Andy:Spoiler anzeigen
[autoit]Func _StringinStrCount($string, $SubString, $bSense = False, $bPartial = False, $sdelim = '', $bReturn = False)
[/autoit]
Local $casesense = "(?-i)", $part1 = "", $part2 = "", $treffer = 0 ;würde auch noch in die nächste zeile passen
Dim $retarray1[2] = [1, StringLen($string)], $retarray[1], $aSplit[1] = [$SubString]
If $SubString = "" And $sdelim = "" And $bReturn = False Then Return StringLen($string) ; :o)
If $SubString = "" And $sdelim = "" Then Return $retarray1
If $SubString = "" And $bReturn = False Then Return UBound(StringRegExp($string, "[^(" & $sdelim & ")]", 3))
If $SubString = "" Then
Dim $retarray2[2] = [1, UBound(StringRegExp($string, "[^(" & $sdelim & ")]", 3))]
Return $retarray2
EndIf
If $sdelim <> "" Then Dim $aSplit = StringSplit($SubString, $sdelim, 2) ;wird der Substring mit dem Trennzeichen gesplittet in ein nullbasiertes Array
If $bSense = False Then $casesense = "(?i)"
If $bPartial = False Then ;der suchbegriff muss alleinstehend sein
$part1 = "(?<![\d|\x{041}-\x{0ff}])" ;vornedran dürfen nur zeichen kleiner ascii0x41 sein aber keine zahlen
$part2 = "(?![\d|\x{041}-\x{0ff}])" ;hintendran dürfen nur leerzeichen sein und satzzeichen oder das textende
EndIf
For $i = 0 To UBound($aSplit) - 1 ;Zählschleife für das splitarray von null bis zur anzahl splitstrings
If $bReturn = False Then $treffer += UBound(StringRegExp($string, $casesense & $part1 & "(" & $aSplit[$i] & ")" & $part2, 3))
ReDim $retarray[UBound($retarray) + 1]
$retarray[0] += 1
$retarray[UBound($retarray) - 1] = UBound(StringRegExp($string, $casesense & $part1 & "(" & $aSplit[$i] & ")" & $part2, 3))
Next
If $bReturn = True Then Return $retarray
Return $treffer
EndFunc ;==>_StringinStrCountBuFix:
Spoiler anzeigen
[autoit]Func _StringInStrCount($sString, $sSearch='' , $bSens=False, $bPartial=False, $sDelim='', $bReturn=False)
[/autoit]
If Not $sSearch And $sDelim Then Return UBound(StringSplit(StringRegExpReplace($sString, $sDelim, ''), '', 2))
If Not $sSearch And Not $sDelim Then Return StringLen($sString)
Local $ret, $Out = '', $indP = 0, $aPat[4][2] = [['(?i)\b','\b'],['\b','\b'],['',''],['(?i)','']]
If $bSens And Not $bPartial Then $indP = 1
If $bSens And $bPartial Then $indP = 2
If Not $bSens And $bPartial Then $indP = 3
If $sSearch And $sDelim Then
Local $split = StringSplit($sSearch, $sDelim, 2), $sum = 0
For $i In $split
$ret = StringRegExp($sString, $aPat[$indP][0] & $i & $aPat[$indP][1], 3)
If IsArray($ret) Then $Out &= UBound($ret) & $sDelim
If IsArray($ret) Then $sum += UBound($ret)
If Not IsArray($ret) Then $Out &= 0 & $sDelim
Next
If $bReturn Then Return StringSplit(StringTrimRight($Out, StringLen($sDelim)), $sDelim)
If Not $bReturn Then Return $sum
EndIf
$ret = StringRegExp($sString, $aPat[$indP][0] & $sSearch & $aPat[$indP][1], 3)
If $bReturn Then Return StringSplit(UBound($ret), ',')
If Not $bReturn Then Return UBound($ret)
EndFunc ; BugFixFunkey:
Spoiler anzeigen
[autoit]Func _StringInStrCount($String, $Substring, $bSens = False, $bPartial = False, $sDelim = '', $bRetType = False)
[/autoit]
Local $iMatch, $aSplitDelim, $aRet[UBound(StringSplit($Substring, $sDelim, 1))], $bCaseSens = '(?i)', $bPartRegExp = '[ \.,!?\n\r"' & "'" & ']{1}'
If $Substring = '' And $sDelim = '' Then Return StringLen($String)
If $Substring = '' And $sDelim <> '' Then Return StringLen(StringReplace($String, $sDelim, ''))
If $bSens Then $bCaseSens = '(?-i)'
If $bPartial Then $bPartRegExp = ''
If $sDelim = '' Then Return UBound(StringRegExp(' ' & StringRegExpReplace($String, $bPartRegExp, ' ') & ' ', $bCaseSens & $bPartRegExp & $Substring & $bPartRegExp, 3))
$aSplitDelim = StringSplit($Substring, $sDelim, 1)
For $i = 1 To UBound($aSplitDelim) - 1
$iMatch += UBound(StringRegExp(' ' & StringRegExpReplace($String, $bPartRegExp, ' ') & ' ', $bCaseSens & $bPartRegExp & $aSplitDelim[$i] & $bPartRegExp, 3))
$aRet[$i] = $iMatch - $aRet[$i - 1]
Next
$aRet[0] = UBound($aRet) - 1
If $bRetType Then Return $aRet
Return $iMatch
EndFuncOscar:
Spoiler anzeigen
[autoit]Func _StringInStrCount($sString, $sSearch = '', $bSens = False, $bPartial = False, $sDelim = '', $bReturn = False)
[/autoit]
If $sSearch = '' Then
$sSearch = '(?s).'
$bPartial = True
EndIf
Local $aSens[2] = ['(?i)', ''], $aPartial[2] = ['\b', ''], $aSearch[2] = [1, $sSearch], $aString[2] = [1, $sString], $iCount = 0
If $sDelim <> '' Then Local $aSearch = StringSplit($sSearch, $sDelim, 1), $aString = StringSplit($sString, $sDelim, 1)
Local $aCount[$aSearch[0] + 1] = [$aSearch[0]]
For $j = 1 To $aString[0]
For $i = 1 To $aSearch[0]
$aString[$j] = StringRegExpReplace($aString[$j], $aSens[$bSens] & $aPartial[$bPartial] & $aSearch[$i] & $aPartial[$bPartial], '')
$aCount[$i] += @extended
$iCount += @extended
Next
Next
If $bReturn Then Return $aCount
Return $iCount
EndFuncNun komme ich zu der schwierigen Aufgabe, einen Gewinner zu ernennen.
Programmiertechnisch hat mir eigentlich Oscar´s Script am besten gefallen, welches jedoch beim Geschwindigkeitstest das langsamste ist.
Und da es gerade in einer Sprach wie Autoit manchmal sehr auf Geschwindigkeit ankommt, wähle ich das (mit Abstand) schnellste Script: BUGFIX!Als Gewinn gibt es ein:
Dann noch vielen Dank an alle Teilnehmer
lgE
-
- Offizieller Beitrag
Gratulation an BugFix!
Geschwindigkeit geht vor, das sehe ich auch so.
Diesbezüglich könnte man das Script von BugFix noch etwas tunen:Spoiler anzeigen
[autoit]
[/autoit]
Func _StringInStrCount($sString, $sSearch = '', $bSens = False, $bPartial = False, $sDelim = '', $bReturn = False)
If Not $sSearch And $sDelim Then Return UBound(StringSplit(StringRegExpReplace($sString, $sDelim, ''), '', 2))
If Not $sSearch And Not $sDelim Then Return StringLen($sString)
Local $ret, $Out = '', $indP = 0, $aPat[4][2] = [['(?i)\b', '\b'],['\b', '\b'],['', ''],['(?i)', '']]
If $bSens And Not $bPartial Then $indP = 1
If $bSens And $bPartial Then $indP = 2
If Not $bSens And $bPartial Then $indP = 3
If $sSearch And $sDelim Then
Local $split = StringSplit($sSearch, $sDelim, 2), $sum = 0
For $i In $split
$ret = StringRegExp($sString, $aPat[$indP][0] & $i & $aPat[$indP][1], 3)
If IsArray($ret) Then
$Out &= UBound($ret) & $sDelim
$sum += UBound($ret)
Else
$Out &= 0 & $sDelim
EndIf
Next
If $bReturn Then Return StringSplit(StringTrimRight($Out, StringLen($sDelim)), $sDelim)
Return $sum
EndIf
$ret = StringRegExp($sString, $aPat[$indP][0] & $sSearch & $aPat[$indP][1], 3)
If $bReturn Then Return StringSplit(UBound($ret), ',')
Return UBound($ret)
EndFunc ;==>_StringInStrCount -
Ja, ja, Geschwindigkeit ist eben alles !
Gratulation Bugfix!Ich bin sicher, dass mittels einer Kombination der besten Teile jedes Skripts noch etwas mehr herauszuholen wäre.
eukalyptus: Wie wirkt sich Oscar's Anpassung von Bugfix' Skript zeitlich aus? -