• 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 ;)

  • 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. :rofl:

  • 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.

  • 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
    Andy

    Spoiler 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)
    _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)

    [/autoit] [autoit][/autoit] [autoit]

    _Check(1, _StringinStrCount($sText, "und", False, False, "", False), 8)
    _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)

    [/autoit] [autoit][/autoit] [autoit]

    _Check(5, _StringinStrCount($sText, "aber", False, False, "", False), 2)
    _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)

    [/autoit] [autoit][/autoit] [autoit]

    _Check(9, _StringinStrCount($sText, "und;aber", False, False, ";", False), 10)
    _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)

    [/autoit] [autoit][/autoit] [autoit]

    _Check(13, _StringinStrCount($sText, "und;aber", False, False, ";", True), "2;8;2")
    _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")

    [/autoit] [autoit][/autoit] [autoit]

    _Check(17, _StringinStrCount($sText, "", False, True, "", False), 119)
    _Check(17, _StringinStrCount($sText, "", False, True, " ", False), 104)
    ConsoleWrite(TimerDiff($t) / 1000 & @CRLF)
    Exit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _StringinStrCount($string, $SubString, $bSense = False, $bPartial = False, $sdelim = '', $bReturn = False)
    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 ;==>_StringinStrCount

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Check($i, $j, $k)
    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

    [/autoit]
  • Hallo BugFix,

    Zitat

    Das 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.

  • Zitat von Andy

    und bevor ich es auch noch "vergesse", stelle ich es lieber online

    Zitat von progandy

    Du hast den Sinn nicht verstanden...

    Zitat von Oscar

    Ich habe leider den Abgabetermin etwas verschlafen

    Zitat von BugFix

    Oops, geht mir genauso

    :rofl::rofl::rofl:;)

    da bleibt mir doch nur ein 8o
    ciao
    Andy

  • da bleibt mir doch nur ein 8o
    ciao
    Andy


    Hmm, dieses Mal ists irgendwie nicht so toll gelaufen... Ich hab meins kaputt optimiert und die Sicherungskopie vergessen :(

    Zitat von Andy

    und 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 Zeilen

    Funkey 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 ms

    Ein 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)
    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 ;==>_StringinStrCount

    [/autoit]

    BuFix:

    Spoiler anzeigen
    [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
    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 ; BugFix

    [/autoit]

    Funkey:

    Spoiler anzeigen
    [autoit]

    Func _StringInStrCount($String, $Substring, $bSens = False, $bPartial = False, $sDelim = '', $bRetType = False)
    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
    EndFunc

    [/autoit]

    Oscar:

    Spoiler anzeigen
    [autoit]

    Func _StringInStrCount($sString, $sSearch = '', $bSens = False, $bPartial = False, $sDelim = '', $bReturn = False)
    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
    EndFunc

    [/autoit]

    Nun 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: :thumbup:

    Dann noch vielen Dank an alle Teilnehmer

    lgE

    • Offizieller Beitrag

    Gratulation an BugFix! :thumbup:
    Geschwindigkeit geht vor, das sehe ich auch so.
    Diesbezüglich könnte man das Script von BugFix noch etwas tunen:

    Spoiler anzeigen
    [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

    [/autoit]