Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/21/2023 in all areas

  1. Well done guys Before someone asks : but how to retrieve the separate strings in an Array, using RegEx, in a subject that includes several literal '\n' . This seems to do the job Edit1: there is no hidden @CRLF or any space at the very end of the subject... @mikell ...and the last group is empty again, no matter I changed '$' to '\z' or '\Z' in the pattern, grr... Edit2: I wish we could use PCRE_NOTEMPTY in AutoIt's PCRE, to get rid of empty groups when needed, but I don't think it's possible (?) Edit3: Just re-read OP's post, the pic above corresponds to a subject where literal '\n' are found and the subject has not been broken into chunks. Then a comma should be inserted in the pattern of the pic above to make it safer, even without adding the space, in case this kind of subject can be found 'Salena Haley,\nCade Batson' . Not feeling into modifying the pic but you got the idea (.*?)(?:,\\n|$) Edit4: As written in Edit1, we see in the pic a 4th "zero-width" match returned with this kind of pattern : (.*?)(?:\\n |$) (.*?)(?:,\\n|$) A solution to avoid the 4th "zero-width" group in this example is to use the + quantifier (1 or more) instead of the * quantifier (0 or more) (.+?)(?:,\\n|$) It's not the 1st time (and certainly not the last) that the choice between * and + eliminates empty groups in the array returned. One should carefully check before if + instead of * won't behave badly when applied to the subject. If not mistaken, there is also the "Non-capturing group with reset (?| ... ) that allows to avoid blank groups to be returned, when used with alternation (e.g | ) and capturing groups placed inside the (?| ... ) but enough for today
    2 points
  2. jchd has some great examples, but here's the helpfile piece that you may have missed (as @jchd said Read Help > Language Reference - Variables > Arrays and Maps): https://www.autoitscript.com/autoit3/docs/intro/lang_variables.htm#ArrayMaps As mentioned, you're mixing up Arrays and Maps, which are two different things. Maps were indeed added in the latest stable release of AutoIt, but have been around for a while in beta. In your example however you are only creating Arrays, to create a map you cannot add any data to it when declaring, it has to be just a plain and simple: Local $mMap[] ; If you specify any data at declaration, it's interpreted as an array The key difference (for most people) between Arrays and Maps is that Arrays are accessed by an index, and Maps by a key. That key can be numeric, but it is not an index. There's a few Map* functions to assist with using them: https://www.autoitscript.com/autoit3/docs/functions/Map Management.htm, though using a map is as simple as: Global $mMap[] ; Create your map $mMap.hTimer = TimerInit() ; Creates a new key and sets the value Sleep(500) ConsoleWrite(Round(TimerDiff($mMap.hTimer), 2) & ' ms' & @CRLF) $mMap.sMsg = 'This is a message, here are the numbers 0-9: ' ; Another new key $mMap.iLoopMax = 10 $mMap.hTimer = TimerInit() ; Update value, start new timer For $i = 0 To $mMap.iLoopMax - 1 $mMap.sMsg &= $i & ', ' Sleep(10) Next $mMap.sMsg = StringTrimRight($mMap.sMsg, 2) ConsoleWrite('sMsg: ' & $mMap.sMsg & ', took: ' & Round(TimerDiff($mMap.hTimer), 2) & ' ms' & @CRLF) ConsoleWrite("You can also access map keys using ['sKey'] syntax: " & $mMap['sMsg'] & ', took: ' & Round(TimerDiff($mMap['hTimer']), 2) & ' ms' & @CRLF) For $i = 0 To $mMap.iLoopMax - 1 $mMap[$i] = Random(0, 9, 1) ; Creating new keys that are numeric, there are not indexes however Next For $i = 0 To $mMap['iLoopMax'] - 1 ConsoleWrite('$mMap[' & $i & ']: ' & $mMap[$i] & @CRLF) Next ; There are couple ways to list everything in the map Global $aMapKeys = MapKeys($mMap) For $iKey = 0 to UBound($aMapKeys) - 1 ConsoleWrite('$aMapKeys[$iKey] - Key: ' & $aMapKeys[$iKey] & ', value: ' & $mMap[$aMapKeys[$iKey]] & @CRLF) Next ; Or this way which just returns the data, but no reference of the key (unless I'm missing something), so MapKeys is preferred For $vValue In $mMap ConsoleWrite('$vValue In $mMap - Value: ' & $vValue & @CRLF) Next If you want to learn more about AutoIt's Maps, I would recommend this page: While it's quite old now and is about Maps when they were still a beta feature, it's still got some good information.
    1 point
  3. Never do a loop without a sleep in any IPC or GUI. It will take 100% CPU for nothing, you always need to put a sleep (10 is minimum) unless you are calculating something. But if you dont care about it, just remove the sleep in my example. $iData has not meaning in itself, it is just a manner to create your own protocol. You need to invent the way how client/server talks to each other. I am just offering a framework for you to develop around it. For example if $iData = 1 it may mean for you that the client Acknowledges it is ready. Dont bother with _WCD_Server_PeekRequest until you feel the need to use it. Now enough questions, start creating your scripts, and come with some tangible programs that we can discuss of.
    1 point
  4. Funny regex challenge My 2 cents Local $s1 = "Marco Scarborough, Chaim Stephenson, Clark Casey, Phoebe Moser, Salena Haley, Cade Batson, Carl Lindsey, Roy Mckenzie, Lillie Peek, Priya Harter, Finn Stratton, Sharon Saxton, Todd Poole, Ariella Findley, Edith Walker" $res1 = StringTrimRight(StringRegExpReplace($s1, ".{1,79}(,|$)\K", "\\n"), 2) Msgbox(0,"", $res1) Local $s2 = "There are usually about 200 words in a paragraph, but this can vary widely. Most paragraphs focus on a single idea that's expressed with an introductory sentence, then followed by two or more supporting sentences about the idea. A short paragraph may not reach even 50 words while long paragraphs can be over 400 words long, but generally speaking they tend to be approximately 200 words in length." $res2 = StringTrimRight(StringRegExpReplace($s2, ".{1,79}(\h|$)\K", "\\n"), 2) Msgbox(0,"", $res2) Edit ...and the func Msgbox(0,"", _WrapText($s1, ",", 80) ) Msgbox(0,"", _WrapText($s2, "\h", 80) ) Func _WrapText($txt, $char, $n) Return StringTrimRight(StringRegExpReplace($txt, '.{1,' & $n-1 & '}(' & $char & '|$)\K', "\\n"), 2) EndFunc Please note that you can write either _WrapText($s2, "\h", 80) or _WrapText($s2, " ", 80) as both work Edit 2 Ooops I didn't see the regex from mistersquirrle... nearly the same
    1 point
  5. This is a bit more difficult and it's something that I've briefly looked into for some things in my job. In the end I didn't get an actual character count break working, just an occurrence thing. It was set to match a pattern 25 times, then replace it with the match and \n. I'm not quite sure that RegEx can reliably do what you're looking for. That being said, I like trying things and I know more now than I did then, so for commas: https://regex101.com/r/ywFNPy/1 ([^\v]{0,80})(?:,|$) And then for spaces/whitespace it's just a simple modification: https://regex101.com/r/HP6gZy/1 ([^\v]{0,80})(?:\s|$) Putting it into AutoIt to test: Local $s1 = "Marco Scarborough, Chaim Stephenson, Clark Casey, Phoebe Moser, Salena Haley, Cade Batson, Carl Lindsey, Roy Mckenzie, Lillie Peek, Priya Harter, Finn Stratton, Sharon Saxton, Todd Poole, Ariella Findley, Edith Walker" Local $s2 = "There are usually about 200 words in a paragraph, but this can vary widely. Most paragraphs focus on a single idea that's expressed with an introductory sentence, then followed by two or more supporting sentences about the idea. A short paragraph may not reach even 50 words while long paragraphs can be over 400 words long, but generally speaking they tend to be approximately 200 words in length." Local $s3 = $s1 & ' ' & $s2 ConsoleWrite(_WrapText($s1, ",") & @CRLF & @CRLF) ConsoleWrite(_WrapText($s2, " ") & @CRLF & @CRLF) ConsoleWrite('---------------------------------' & @CRLF & @CRLF) ConsoleWrite('RegEx output, Auto:' & @CRLF & _WrapText_RegEx($s3, 0, 80) & @CRLF & @CRLF) ConsoleWrite('RegEx output, comma:' & @CRLF & _WrapText_RegEx($s1, 1, 80) & @CRLF & @CRLF) ConsoleWrite('RegEx output, whitespace:' & @CRLF & _WrapText_RegEx($s2, 2, 80) & @CRLF & @CRLF) Exit Func _WrapText($sTxt, $sChar) Local $iMaxLen = 80 Local $iLen = StringLen($sTxt) Local $sWrapped = "" Local $iStartPos = 1 Local $iRemaining = $iLen While $iRemaining > $iMaxLen Local $iWrapPos = StringInStr(StringMid($sTxt, $iStartPos, $iMaxLen), $sChar, 0, -1) ;~ $sWrapped &= StringMid($sTxt, $iStartPos, $iWrapPos) & "\n" $sWrapped &= StringMid($sTxt, $iStartPos, $iWrapPos) & @CRLF $iStartPos += ($iWrapPos) $iRemaining = $iLen - $iStartPos + 1 If $iRemaining <= $iMaxLen Then $sWrapped &= StringRight($sTxt, $iRemaining) WEnd $sTxt = $sWrapped Return $sTxt EndFunc ;==>_WrapText Func _WrapText_RegEx($sTxt, $iMode = 0, $iLineMaxLength = 80) ; iMode, 0 = Auto, 1 = comma, 2 = whitespace If $iMode = Default Then $iMode = 0 If $iMode > 2 Or $iMode < 0 Then $iMode = 0 If $iLineMaxLength = Default Then $iLineMaxLength = 80 Local $sPatternComma = '([^\v]{0,' & $iLineMaxLength & '})(,|$)' Local $sPatternWhitespace = '([^\v]{0,' & $iLineMaxLength & '})(\s|$)' Local $sPatternAuto = '([^\v]{0,' & $iLineMaxLength & '})(,|\s|$)' Local $sOutput1, $sOutput2, $sReturn Local $aLines1, $aLines2 Local $iLines1, $iLines2 Switch $iMode Case 0 ; Auto, choose whichever produces the least amount of lines, though it may cause lines over 80 characters (when there's not a comma to break on #cs $sOutput1 = StringRegExpReplace($sTxt, $sPatternComma, '$1' & @CRLF) ; Get a count of how many lines there are. Alternatively and likely better is StringReplace for both @LF and @CR and add the @extended $aLines1 = StringSplit($sOutput1, @CRLF, 2) $iLines1 = UBound($aLines1) $sOutput2 = StringRegExpReplace($sTxt, $sPatternWhitespace, '$1' & @CRLF) $aLines2 = StringSplit($sOutput2, @CRLF, 2) $iLines2 = UBound($aLines2) If $iLines1 <= $iLines2 Then $sReturn = $sOutput1 Else $sReturn = $sOutput2 EndIf #ce $sReturn = StringRegExpReplace($sTxt, $sPatternAuto, '$1$2' & @CRLF) Case 1 ; Comma $sReturn = StringRegExpReplace($sTxt, $sPatternComma, '$1$2' & @CRLF) Case 2 ; Whitespace $sReturn = StringRegExpReplace($sTxt, $sPatternWhitespace, '$1$2' & @CRLF) EndSwitch Return StringStripWS($sReturn, 1 + 2) ; $STR_STRIPLEADING + $STR_STRIPTRAILING EndFunc ;==>_WrapText_RegEx Seems to work to me, the only thing is that I'm not keeping the trailing comma or whitespace. It's probably easier to simple add that into the replace with $1,\n, but if you do that make sure that you're adjusting your line/character length -1 for the comma (whitespace one can probably just be dropped). Edit: I just realized that for my 'Auto', I could just combine looking for either a whitespace or a comma, duh. Updated code. Also updated to keep commas, though I don't have a check to make sure that with the comma it doesn't go over 80 characters to 81. Simple way for $iMode = 1 is to set $iLineMaxLength - 1 Edit 2: I also compared the speed of both, and the RegEx is faster: Runs: 100000 1) "_WrapText" ('_WrapText($s2, " ")') time elapsed: 5609.60 ms 2) "_WrapText_RegEx" ('_WrapText_RegEx($s2)') time elapsed: 3541.02 ms #Fastest Function: "_WrapText_RegEx"
    1 point
  6. I imagine that you'll have to handle the sanitization of the $sArgs yourself, likely disallow anything after "&" for example as a first step to prevent a second command from being run. This function may also be of interest when first thinking about your problem (since I recently was looking at it): _WinAPI_PathGetArgs - https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_PathGetArgs.htm But reading its remarks make me think then again maybe not: "This function should not be used on generic command path templates (from users or the registry), but rather should be used only on templates that the application knows to be well formed." The other option would be that if you know what CMD things shouldn't be allowed, only parse $sArgs up to that point. I'm certainly no Windows/CMD guru, but I know at least "&" and "|" should probably be blocked (unless contained inside quotes, maybe?). So you could try some RegEx. I think some of the simplest you could do would be: (^[^&|]*) That should only return/match everything until the first "&" or "|". If you NEED to be able to match those characters as part of a parameter, it likely starts becoming more complex. Reading up a little, you can use a caret "^" to escape special characters as well, so you could prefix any 'special' character with ^ and likely just end up invalidating the whole command: Global $sEscapePattern = '([&|()<>])' ; Technically ^ may be a character you want to replace. Func __Sanitize_RegEx($sString) Return StringRegExpReplace($sString, $sEscapePattern, '^$1') EndFunc It might be easier to help or answer the question if you can give any examples of what you're expecting to encounter, or potential valid/invalid uses.
    1 point
  7. Without using Execute StringRegExpReplace($sText1, '\G\h|\h(?=\h*$)' ,"*")
    1 point
  8. No, this doesn't work. GUIGetStyle only works with Au3-Windows. Use this instead $hWin = WinGetHandle("Untitled") $fTopMost = _WinIsOnTop($hWin) If $fTopMost Then ConsoleWrite("Debug: Window with handle $hWin has $WS_EX_TOPMOST set.") Else ConsoleWrite("Debug: Window with handle $hWin does not have $WS_EX_TOPMOST set.") EndIf ;=============================================================================== ; ; Function Name: _WinIsOnTop ; Description:: Gets the OnTop State of a window ; Parameter(s): $WindowHandle : Handle or Title of Window ; Requirement(s): WinAPI.au3 ; Return Value(s): Window OnTop: True, otherwise False ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _WinIsOnTop($WindowHandle) Local $long = DllCall("User32.dll", "int", "GetWindowLong", "hwnd", WinGetHandle($WindowHandle), "int", -20) Return BitAND($long[0],8)=8 ; $WS_EX_TOPMOST = 8 EndFunc
    1 point
  9. SmOke_N

    Replace LINE in textfile

    Local $hFile = 'MyFile.txt', $aFile = StringSplit(StringStripCR(FileRead($hFile)), @LF), $sHold For $iCC = 1 To $aFile[0] If StringInStr($aFile[$iCC], 'String I am looking for') Then _ $aFile[$iCC] = 'New Text In Place Of Current Line' $sHold &= $aFile[$iCC] & @CRLF Next FileClose(FileWrite(FileOpen($hFile, 2), StringTrimRight($sHold, StringLen(@CRLF)))) I wrote this in the Fast Reply box, so be sure to check for errors. Edit: Yep, found 1. Edit2: Ok, found 2 more, last time I do it in Fast Reply
    1 point
×
×
  • Create New...