Jump to content

dany

Active Members
  • Posts

    223
  • Joined

  • Last visited

  • Days Won

    2

dany last won the day on November 21 2012

dany had the most liked content!

About dany

  • Birthday 11/09/1976

Recent Profile Visitors

601 profile views

dany's Achievements

Polymath

Polymath (5/7)

34

Reputation

  1. Thanks for the sample code czardas I ran these tests: Global $sStr = '' For $i = 1 To 10000000 $sStr &= Chr(Random(1, 255, 1)) ; Monster string for testing. Next MsgBox(0, 'Info', 'Test String Created') Global $sDelim = _GetDelim($sStr) MsgBox(0, 'Delim', Binary($sDelim)) ; Show control characters. MsgBox(0, 'StringInStr?', StringInStr($sStr, $sDelim)) Func _GetDelim($sTest) Local $sDelim = Chr(1) While StringInStr($sTest, $sDelim) $sDelim &= Chr(Random(1, 31, 1)) If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) WEnd Return $sDelim EndFunc Response time is relatively slow due to the monster test string. _GetDelim itself takes 1-3 iterations to find a unique delimiter. I'm happy with that, the delimiter is 2-3 characters on average. A lookup on a 10 million character string takes some time, I didn't measure exactly but roughly 1-2 seconds before the delimiter pops up. I reduced that by checking only the first 100000 characters of the string, but that's too small a sample, I got collisions outside the test range. Same for a 1 million test sample, it performs better but only marginally, you get collisions now and then. I took out the Random and took your sequential approach: Func _GetDelim($sTest) Local $sDelim ;$sTest = StringLeft($sTest, 1000000) ; Reduced test sample. For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sTest, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) Next Return $sDelim EndFunc I haven't kept exact stats but on gut feeling I'd say it performs only marginally better because there's one less function call. When testing a smaller sample range (1 million) it gives less collisions, but it still isn't foolproof. So as far as methods go, I'd say the sequential approach is marginally faster but not much. I simplified the function because I feel matters shouldn't be made overly complicated. Any unique sequence of characters will do, it's just a throw-away value anyway so the simplest approach will suffice. I don't see a way to reduce overall speed for very large monster strings though. So this would be my proposed version, corrections and all: ; #FUNCTION# =================================================================== ; Name...........: _StringRegExpSplit ; Description ...: Split a string according to a regular exp[b][/b]ression. ; Syntax.........: _StringRegExpSplit($sString, $sPattern) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular exp[b][/b]ression to split on. ; Return values .: Success - Array: Array of substrings, the total is in $array[0]. ; Failure - Array: The count is 1 ($array[0]) and the full string is returned ($array[1]) and sets @error: ; |1 Delimiter not found. ; |2 Bad RegExp pattern, @extended contains the offset of the error in the pattern. ; |3 No suitable placeholder delimiter could be constructed. ; Author ........: dany ; Modified ......: czardas, AZJIO ; Remarks .......: ; Related .......: ; ============================================================================== Func _StringRegExpSplit($sString, $sPattern) Local $sSplit, $sDelim, $aError[2] = [1, $sString] For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sString, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, $aError) WEnd $sSplit = StringRegExpReplace($sString, $sPattern, $sDelim) If @error Then Return SetError(2, @extended, $aError) If @extended = 0 Then Return SetError(1, 0, $aError) If Not IsBinary($sString) Then Return StringSplit($sSplit, $sDelim, 1) $sSplit = StringSplit($sSplit, $sDelim, 1) For $i = 2 To $sSplit[0] $sSplit[$i] = '0x' & $sSplit[$i] Next Return $sSplit EndFunc
  2. Only $ and arn't 'allowed': #include <Array.au3> $sString = 'why hello there' $sDelim = '^.*+|/?-[]{}()' $sReplaced = StringRegExpReplace($sString, ' ', $sDelim) MsgBox(0, '...', $sReplaced) _ArrayDisplay(StringSplit($sReplaced, $sDelim, 1), ':)')
  3. Thanks for your suggestions, czardas and AZJIO. You're right about the delimiter being overly long but it was primarily meant as an example, although the longer the delimiter the less efficient the string lookup and replacing becomes... Here's my revised version, it generates a temp delimiter on the fly that always starts with Chr(1). There's also a little part at the end to correct the array entries when the string passed was binary. edit: ; #FUNCTION# =================================================================== ; Name...........: _StringRegExpSplit ; Description ...: Split a string according to a regular exp<b></b>ression. ; Syntax.........: _StringRegExpSplit($sString, $sPattern) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular exp<b></b>ression to split on. ; Return values .: Success - Array: Array of substrings, the total is in $array[0]. ; Failure - Array: The count is 1 ($array[0]) and the full string is returned ($array[1]) and sets @error: ; |1 Delimiter not found. ; |2 Bad RegExp pattern, @extended contains the offset of the error in the pattern. ; |3 No suitable placeholder delimiter could be constructed. ; Author ........: dany ; Modified ......: czardas, AZJIO ; Remarks .......: ; Related .......: ; ============================================================================== Func _StringRegExpSplit($sString, $sPattern) Local $sSplit, $aError[2] = [1, $sString], $sDelim = Chr(1) While StringInStr($sString, $sDelim) $sDelim &= Chr(Random(0, 255, 1)) If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) WEnd $sSplit = StringRegExpReplace($sString, $sPattern, $sDelim) If @error Then Return SetError(@error, @extended, $aError) If @extended = 0 Then Return SetError(1, 0, $aError) If Not IsBinary($sString) Then Return StringSplit($sSplit, $sDelim, 1) $sSplit = StringSplit($sSplit, $sDelim, 1) For $i = 2 To $sSplit[0] $sSplit[$i] = '0x' & $sSplit[$i] Next Return $sSplit EndFuncExample: #include <Array.au3> Global $sString = 'list:1.a2.b3.c' _ArrayDisplay(_StringRegExpSplit($sString, '[0-9]+.')) Global $bBinary = Binary($sString) _ArrayDisplay(_StringRegExpSplit($bBinary, '3[0-9]2E'))
  4. Well no, it's just a different format, the problem stays the same. The non-hex character might just be the data I want to keep. I chose ___SPLIT___ because it's rather unlikely to turn up in everyday sentences. Your question is valid nonetheless and I'm intrigued by the offered solutions. But it would be easier to just change it to ___STRING___REGEXP___SPLIT___. You could check for ___SPLIT___ in the string and in the highly unlikely case it's in there use another overly long placeholder, put a few in an array and loop over them. Chances on collisions are very small and placeholders are a much used technique in template parsers, see the Wiki markup language. edit: ; #FUNCTION# =================================================================== ; Name...........: _StringRegExpSplit ; Description ...: Split a string according to a regular exp<b></b>ression. ; Syntax.........: _StringRegExpSplit($sString, $sPattern) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular exp<b></b>ression to split on. ; Return values .: Success - Array: Array of substrings, the total is in $array[0]. ; Failure - Array: The count is 1 ($array[0]) and the full string is returned ($array[1]) and sets @error: ; |1 Delimiter not found. ; |2 Bad RegExp pattern, @extended contains the offset of the error in the pattern. ; Author ........: dany ; Modified ......: ; Remarks .......: ; Related .......: ; ============================================================================== Func _StringRegExpSplit($sString, $sPattern) Local $iDelim, $aDelim[4] = ['___SPLIT___', '___STRING___REGEXP___SPLIT___', '___SPLIT_DELIMITER___', 0] Local $aRet[2] = [1, $sString], $sSplit For $iDelim = 0 To 3 If Not StringInStr($sString, $aDelim[$iDelim]) Then ExitLoop Next If 3 = $iDelim Then Return SetError(3, 0, 0) ; All possible delimiters are in the string! $sSplit = StringRegExpReplace($sString, $sPattern, $aDelim[$iDelim]) If @error Then Return SetError(2, @extended, $aRet) If 0 = @extended Then Return SetError(1, 0, $aRet) Return StringSplit($sSplit, $aDelim[$iDelim], 1) EndFunc ;==>_StringRegExpSplit edit: sorry, posted incomplete code. You could also generate a random alphanumeric string on the spot and use that as a placeholder delimiter. edit 2: I'll look into a better revised version tonight, gotta go to work
  5. Edit: A function to split a string based on a regular expression. ; _StringRegExpSplit example. Global $sString = '1. A numbered list.' & @CRLF & _ '2. Second item.' & @CRLF & _ '3. Last item.' Global $aListItems = _StringRegExpSplit($sString, '[0-9]+. ') ; #FUNCTION# =================================================================== ; Name...........: _StringRegExpSplit ; Description ...: Split a string according to a regular exp[b][/b]ression. ; Syntax.........: _StringRegExpSplit($sString, $sPattern) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular exp[b][/b]ression to split on. ; Return values .: Success - Array: Array of substrings, the total is in $array[0]. ; Failure - Array: The count is 1 ($array[0]) and the full string is returned ($array[1]) and sets @error: ; |1 Delimiter not found. ; |2 Bad RegExp pattern, @extended contains the offset of the error in the pattern. ; Author ........: dany ; Modified ......: ; Remarks .......: ; Related .......: ; ============================================================================== Func _StringRegExpSplit($sString, $sPattern) Local $aRet[2] = [1, $sString], $sSplit = StringRegExpReplace($sString, $sPattern, '___SPLIT___') If @error Then Return SetError(2, @extended, $aRet) If 0 = @extended Then Return SetError(1, 0, $aRet) Return StringSplit($sSplit, '___SPLIT___', 1) EndFunc ;==>_StringRegExpSplit
  6. If you want to plugin a USB and autorun a program from the USB all automated, then no it can't be done. With any luck a window will popup and from there you can start your program manually. In any other case the program has to be installed on the computer and already be running before you plugin the USB. The program could monitor any mount points and act accordingly if a new one gets added.
  7. I should have refreshed
  8. Anyone of these I imagine: Const REG_SZ = 1 Const REG_EXPAND_SZ = 2 Const REG_BINARY = 3 Const REG_DWORD = 4 Const REG_MULTI_SZ = 7I don't know if you need the numeric or string value though. edit: I based it on this article but on second look was a bit hasty and I'm wrong. It looks like the variable is passed as a reference like ByRef: Global $strValue $oReg.GetStringValue($HKLM, $Path, $ValName, $strValue) MsgBox(0, " strValue ", $strValue)
  9. Yea, in b4 that solved it.
  10. Don't start or load SQLite and let vergleiche_zeitstempel() simply return 1 without running a query. Then we'll see if SQLite is really the problem or if it's something else.
  11. The ? inverts greediness of the * quantifier. Normally * is very hungry and will eat everything up until the very last </script>. The ? puts it on a diet and tells it to stop a the very first occurence. ConsoleWrite outputs eveything as ANSI, so that's why you get squares.
  12. Then you'll have to do something like this: #include <Crypt.au3> _Crypt_Startup() ; Assuming $aAListOfFilesInAFolder is an array of file names. For $i = 1 To $aAListOfFilesInAFolder[0] $sFileContent = FileRead( $aAListOfFilesInAFolder[$i]) ; Third parameter should be True for the last iteration. $sHash = _Crypt_HashData($sFileContent, $CALG_MD5, False, $sHash) Next _Crypt_Shutdown()
  13. @CRLF equals rn match rn against your group, first entry rn; a hit! Next character ?, does the group repeat? No, doesn't match regex pattern. Back to start of string. match rn against your group, second entry r; a hit! Next character n, does the group repeat? match n against your group, third entry; a hit! Two hits satisfies the quantifier {2,} ... Next character ?, does the group repeat? No, doesn't satisfy the quantifier {3,}
  14. I understand. Well, _GetXML is a very nice generic approach for XML. It works great on simple queries but it can be a pita when you really want to deep probe. It's a good starter though. Meh, took a different approach as the RegExp was becoming a real beasty. Works but not nice... #include <Array.au3> Local $sFile = '', $sXml = '' Local $aGroups, $sGroup, $aHosts $sFile = 'hlist.xml' $sXml = FileRead($sFile) $aGroups = StringSplit($sXml, '</group>', 3) _ArrayDisplay($aGroups) Dim $aHosts[UBound($aGroups)] For $i = 0 To UBound($aGroups) - 1 If $aGroups[$i] = '' Then ContinueLoop ; Skip empty entry from StringSplit. $sGroup = StringRegExp($aGroups[$i], '(?i)<group name="(.+)">', 1) $aHosts[$i] = StringRegExp($aGroups[$i], '<name>(.+)</name>', 3) $aGroups[$i] = $sGroup[0] _ArrayDisplay($aHosts[$i]) Next
  15. Yea, tricky one... still working on it. in the mean time, wouldn't it be easier to use or maybe even _GetXML?
×
×
  • Create New...