Hallo,
Wie kann herausfinden wenn in einem String z.b ein " ! " vorkommt , irgendwo mittendrin ?
mfg
Hallo,
Wie kann herausfinden wenn in einem String z.b ein " ! " vorkommt , irgendwo mittendrin ?
mfg
Hi,
Please press F1 to continue......
Hilfe -> StringInStr ()
;-))
Stefan
OB in einem String ein ! vorkommt kannst du so prüfen:
[autoit]$string="Hallo, das ist ein Test!"
stringreplace($string,"!","!")
if @extended then msgbox(0,0,"Das ! ist im string enthalten")
Die Position des ! im String findest du per
[autoit]$string="Hallo, das ist ein Test!"
$position=stringinstr($string,"!")
if $position then msgbox(0,0,"Das ! ist im string enthalten an Position "&$position)
Warum empfiehlst du die Methode per StringReplace wenn er wirklich nur suchen will?
Ein If StringInStr($String, "c") Then sollte doch übersichtlicher sein.
Außerdem auch schneller weil der String intern nur Readonly gesetzt werden braucht und vor allem weil StringInStr beim ersten Vorkommen die Suche abbricht während StringReplace logischerweise weitermacht.
Also hat das irgendeinen anderen Hintergrund den ich bisher nicht beachtet habe?
Weil sonst würde ich ja nicht wirklich für die Überprüfung zu StringReplace raten.
StringReplace könnte interessant werden, wenn man zusätzlich die genau Anzahl der ! im String benötigt.
ZitatStringReplace könnte interessant werden, wenn man zusätzlich die genau Anzahl der ! im String benötigt
erstens das und weil es auch die wesentlich schnellere Variante ist.( bei großen Strings bis zu 7x schneller)
Zitatund vor allem weil StringInStr beim ersten Vorkommen die Suche abbricht
aber nur, wenn man das auch vorschreibt
[autoit]stringinstr($string,"!",0,1)
[/autoit]StringReplace könnte interessant werden, wenn man zusätzlich die genau Anzahl der ! im String benötigt.
Wie ich ja sagte - es geht hier rein um den Anwendungsfall das nur geprüft werden soll OB er vorkommt - nicht mehr.
und weil es auch die wesentlich schnellere Variante ist.
Sorry - bei mir nicht - in meinen Durchläufen war StringInStr immer schneller:
Global $String = "!agdshgnsdgsdhgpüömf-asldgmstgü+pksletiosetjsehtgisdogj;dfligxjxlignxclkgndglksdnglkdgnldkngdfg fsdf dsfsdfndf?"
Global $Timer, $N = 10000, $Temp
ConsoleWrite("---- Teilstring am Anfang -------------" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
If StringInStr($String, "!") Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringInStr : " & Round($Timer / $N, 4) & "ms" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
StringReplace($String, "!", "!")
If @extended Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringReplace : " & Round($Timer / $N, 4) & "ms" & @CRLF & @CRLF)
ConsoleWrite("---- Teilstring am Ende -------------" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
If StringInStr($String, "?") Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringInStr : " & Round($Timer / $N, 4) & "ms" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
StringReplace($String, "?", "?")
If @extended Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringReplace : " & Round($Timer / $N, 4) & "ms" & @CRLF & @CRLF)
ConsoleWrite("---- Teilstring nicht vorhanden -------------" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
If StringInStr($String, ".") Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringInStr : " & Round($Timer / $N, 4) & "ms" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
StringReplace($String, ".", ".")
If @extended Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringReplace : " & Round($Timer / $N, 4) & "ms" & @CRLF & @CRLF)
( bei großen Strings bis zu 7x schneller)
Bei großen Strings wird der Unterschied erst richtig krass - aber nicht zugunsten der Methode mit StringReplace:
#include <INet.au3>
Global $String = _INetGetSource ("http://autoit.de/")
Global $Timer, $N = 100, $Temp
[/autoit] [autoit][/autoit] [autoit]$Timer = TimerInit()
For $i = 1 To $N
If StringInStr($String, "!") Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringInStr : " & Round($Timer / $N, 4) & "ms" & @CRLF)
$Timer = TimerInit()
For $i = 1 To $N
StringReplace($String, "!", "!")
If @extended Then $Temp = True
Next
$Timer = TimerDiff($Timer)
ConsoleWrite("StringReplace : " & Round($Timer / $N, 4) & "ms" & @CRLF & @CRLF)
Also wo hast du die Angabe her dass das 7x schneller sein soll?
Ich kann das beim besten Willen bei mir nicht reproduzieren.
aber nur, wenn man das auch vorschreibt
[autoit]stringinstr($string,"!",0,1)
[/autoit]
Warum? - das sind Default-Werte.
Hi,
habe einen Vergleich von AutoIt-Funktionen und auch externen dll´s gemacht.
Die Boyer-Moore.dll (freundlicherweise von einem hiesigen Forenmitglied Namens AspirinJunkie in C erstellt) und die Funktion Findbytes() aus der prospeed.dll sind auch am Start.
$post = "Die Vögel singen im Wald abcdefghijklmnopqrstuvwxyz"
$Pattern = $post
$pre = ""
$string = ""
$hDll = DllOpen("Boyer-Moore.dll")
$S_DLL = DllOpen("prospeed.dll")
ConsoleWrite(" Stringlänge Suchzeit Boyer-Moore StringInstr FindBytes StringRegExp Stringreplace" & @CRLF)
For $i = 1 To 18
For $s = 1 To 100
$string &= Chr(Random(35, 127, 1))
Next
$string = StringReplace($string, $post, "") ; $post löschen
$string &= $string & $post ;string aufpumpen und den $post und ans ende bringen
$t = TimerInit()
$a1 = BoyerMoore($string, $Pattern, $hDll) ;Boyer-Moore by AspirinJunkie
$m1 = TimerDiff($t)
$t = TimerInit()
$a2 = StringInStr($string, $Pattern)
$m2 = TimerDiff($t)
$t = TimerInit()
$a3 = _findbytes($string, $Pattern, 0) ;Assemblercode by Frank Abbing
$m3 = TimerDiff($t)
$t = TimerInit()
$a = StringRegExp($string, $Pattern)
$m4 = TimerDiff($t)
$t = TimerInit()
StringReplace($string, $Pattern, "", 1, 2)
if @extended then $x=true
$m5 = TimerDiff($t)
ConsoleWrite(StringFormat(" %10.10s ", StringLen($string)) & _
StringFormat(" %5.10s ", $m1) & _
StringFormat(" %5.10s ", $m2) & _
StringFormat(" %5.10s ", $m3) & _
StringFormat(" %5.10s ", $m4) & _
StringFormat(" %5.10s ", $m5) & @CRLF)
Next
Func BoyerMoore(ByRef $sString, ByRef $sPattern, $hDll = 0)
Local $aRet = DllCall($hDll, "str", "boyerMoore", "str", $sPattern, "str", $sString)
If @error Then Return SetError(2, @error, '')
Return $aRet[0]
EndFunc ;==>BoyerMoore
Func _findbytes($string_1, $string_2, $count)
$struct_1 = DllStructCreate("ubyte[" & StringLen($string_1) & "]")
$struct_2 = DllStructCreate("ubyte[" & StringLen($string_2) & "]")
DllStructSetData($struct_1, 1, $string_1)
DllStructSetData($struct_2, 1, $string_2)
$pos = FindBytes(DllStructGetPtr($struct_1), $count, DllStructGetSize($struct_1), DllStructGetPtr($struct_2), DllStructGetSize($struct_2)) + 1
;MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$pos' & @lf & @lf & 'Return:' & @lf & $pos) ;### Debug MSGBOX
$struct_1 = 0
$struct_2 = 0
If $pos = -1 Or $pos = StringLen($string_1) + 1 Then Return 0
Return $pos
EndFunc ;==>_findbytes
Func FindBytes($B,$O,$A,$S,$L) ;auszug aus der prospeed.au3
$S_FindBytes = DllCall($S_DLL, "long", "FindBytes", _
"long", $B, _
"long", $O, _
"long", $A, _
"long", $S, _
"long", $L)
Return $S_FindBytes[0]
EndFunc
die beiden benötigten dll´s autoit.de/wcf/attachment/7640/
das ganze sieht dann so aus:
Stringlänge Suchzeit Boyer-Moore StringInstr FindBytes StringRegExp Stringreplace
251 0.11258414 0.02374603 0.11900953 0.04413968 0.00949841
651 0.07682540 0.05028572 0.08995556 0.02877460 0.01229206
1451 0.08213334 0.11006985 0.08436826 0.04469841 0.01760000
3051 0.10308572 0.22991748 0.09274921 0.07850159 0.02877460
6251 0.13605081 0.47017148 0.12375874 0.14554922 0.07514921
12651 0.22796193 0.95682551 0.17292700 0.28914289 0.12599366
25451 0.41346036 1.92007643 0.32126988 0.58359372 0.27713019
51051 0.82720010 3.90217192 0.58247626 1.14735252 0.52408895
102251 1.64043195 6.92713738 1.19428586 2.37041299 1.09818426
204651 2.95205116 16.5526624 2.24162568 4.56594343 2.34666696
409451 6.11781664 28.3343274 4.53102279 9.34196944 4.43492119
819051 12.3063126 59.2664710 8.59997569 18.5048658 8.95532812
1638251 24.1173109 116.817081 17.9654118 37.4114587 18.3084721
3276651 50.3566794 227.962492 35.8495283 73.9750443 37.9525889
6553451 103.278209 499.063428 74.6891015 145.018431 72.9321743
13107051 205.247594 912.923569 146.207967 292.947846 158.535512
26214251 384.400531 1813.14245 264.051436 566.840478 286.017915
52428651 766.900541 3617.06166 535.991306 1134.43077 577.359971
Alles anzeigen
Was man sehr deutlich sieht ist die vernachlässigbar minimale Abweichung der unterschiedlichen Verfahren bei "kleinen" Strings. Ich verwende sehr gerne StringInstr() und überhaupt die AutoIt-Stringbefehle, bin nicht so der RegExp-Fuzzi^^
Aber bei der Suche in vielen (sehr) großen Dateien ist es ein Unterschied, ob man 10 Minuten auf ein Ergebnis wartet oder nur 1.5 Minuten. Übrigens ist das "alte" DOS-Programm FIND.EXE nur sehr schwer zu toppen (i love it^^)
AspirinJunkie
Btw, deine dll bzw der Algorithmus an sich profitiert von der Länge des Suchstrings, je länger der Suchstring, desto schneller.Ein Bekannter von mir sucht große Muster in sehr großen Dateien, ich soll dir bestellen, deine dll sei absolute Spitze und wenn du mal zufällig in Rheinhessen auf einem Weinfest einschlagen solltest sag vorher Bescheid, dann brauchst du dir über die Getränkeversorgung keine Gedanken mehr machen :o)
In Anlehnung an Beerware haben wir bei uns die SpätleseWare eingeführt, ein sehr gefälliges Lizenzmodell....:)
/EDIt/ natürlich sieht es anders aus, wenn casesensitiv gesucht wird! Dann ist stringinstr() nicht zu schlagen....
[autoit]StringInStr($string, $Pattern,1) ;Groß- und Kleinschreibung wird berücksichtigt!
[/autoit]Die Boyer-Moore.dll (freundlicherweise von einem hiesigen Forenmitglied Namens AspirinJunkie in C erstellt)
Der Code war eigentlich nur die Umsetzung des Wikipedia-Artikels - da war nicht viel Eigengrips im Spiel.
Bisher war ich nicht sehr aktiv was C und C++ Programmierung angeht - momentan bin ich aber sehr intensiv dabei C++ effektiv im Rahmen meiner Studienarbeit zu erlernen.
Ich kann gerne in dem Zusammenhang aus Übungszwecken mal sehen was ich noch aus der DLL rausholen kann aber momentan hab ich eh bisschen Probleme DLLs von C++ in AutoIt zu nutzen.
Sei´s drum - Back to Topic: Können wir uns darauf einigen das wir als allgemeine Empfehlung zur reinen Überprüfung von Teilstrings StringInStr vorschlagen?
Ein Bekannter von mir sucht große Muster in sehr großen Dateien, ich soll dir bestellen, deine dll sei absolute Spitze und wenn du mal zufällig in Rheinhessen auf einem Weinfest einschlagen solltest sag vorher Bescheid, dann brauchst du dir über die Getränkeversorgung keine Gedanken mehr machen
Darauf komm ich zurück!
Hab allgemein mit Rheinländern sehr gute Erfahrungen gemacht.
Ich selbst wohn an der Elbe und da liegen mir andere Flussbewohner wohl besonders
ZitatSei´s drum - Back to Topic: Können wir uns darauf einigen das wir als allgemeine Empfehlung zur reinen Überprüfung von Teilstrings StringInStr vorschlagen?
Abber sischäääärrr!